/* * 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 . */ package com.l2jserver.gameserver.network.serverpackets; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import com.l2jserver.L2DatabaseFactory; import com.l2jserver.gameserver.datatables.ClanTable; import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager; import com.l2jserver.gameserver.model.CharSelectInfoPackage; import com.l2jserver.gameserver.model.L2Clan; import com.l2jserver.gameserver.model.itemcontainer.Inventory; import com.l2jserver.gameserver.network.L2GameClient; import javolution.util.FastList; /** * This class ... * * @version $Revision: 1.8.2.4.2.6 $ $Date: 2005/04/06 16:13:46 $ */ public class CharSelectionInfo extends L2GameServerPacket { // d SdSddddddddddffddddddddddddddddddddddddddddddddddddddddddddddffd private static final String _S__1F_CHARSELECTINFO = "[S] 09 CharSelectInfo"; private static Logger _log = Logger.getLogger(CharSelectionInfo.class.getName()); private String _loginName; private int _sessionId, _activeId; private CharSelectInfoPackage[] _characterPackages; /** * @param _characters */ public CharSelectionInfo(String loginName, int sessionId) { _sessionId = sessionId; _loginName = loginName; _characterPackages = loadCharacterSelectInfo(); _activeId = -1; } public CharSelectionInfo(String loginName, int sessionId, int activeId) { _sessionId = sessionId; _loginName = loginName; _characterPackages = loadCharacterSelectInfo(); _activeId = activeId; } public CharSelectInfoPackage[] getCharInfo() { return _characterPackages; } @Override protected final void writeImpl() { writeC(0x09); int size = (_characterPackages.length); writeD(size); // Can prevent players from creating new characters (if 0); (if 1, the client will ask if chars may be created (0x13) Response: (0x0D) ) writeD(0x07); writeC(0x00); long lastAccess = 0L; if (_activeId == -1) { for (int i = 0; i < size; i++) { if (lastAccess < _characterPackages[i].getLastAccess()) { lastAccess = _characterPackages[i].getLastAccess(); _activeId = i; } } } for (int i = 0; i < size; i++) { CharSelectInfoPackage charInfoPackage = _characterPackages[i]; writeS(charInfoPackage.getName()); writeD(charInfoPackage.getCharId()); writeS(_loginName); writeD(_sessionId); writeD(charInfoPackage.getClanId()); writeD(0x00); // ?? writeD(charInfoPackage.getSex()); writeD(charInfoPackage.getRace()); if (charInfoPackage.getClassId() == charInfoPackage.getBaseClassId()) writeD(charInfoPackage.getClassId()); else writeD(charInfoPackage.getBaseClassId()); writeD(0x01); // active ?? writeD(charInfoPackage.getX()); // x writeD(charInfoPackage.getY()); // y writeD(charInfoPackage.getZ()); // z writeF(charInfoPackage.getCurrentHp()); // hp cur writeF(charInfoPackage.getCurrentMp()); // mp cur writeD(charInfoPackage.getSp()); writeQ(charInfoPackage.getExp()); writeD(charInfoPackage.getLevel()); writeD(charInfoPackage.getKarma()); // karma writeD(charInfoPackage.getPkKills()); writeD(charInfoPackage.getPvPKills()); writeD(0x00); writeD(0x00); writeD(0x00); writeD(0x00); writeD(0x00); writeD(0x00); writeD(0x00); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIRALL)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_REAR)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LEAR)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_NECK)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_RFINGER)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LFINGER)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HEAD)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_RHAND)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LHAND)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_GLOVES)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_CHEST)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LEGS)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_FEET)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_BACK)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LRHAND)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIR)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIR2)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_RBRACELET)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LBRACELET)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO1)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO2)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO3)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO4)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO5)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO6)); writeD(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_BELT)); writeD(charInfoPackage.getHairStyle()); writeD(charInfoPackage.getHairColor()); writeD(charInfoPackage.getFace()); writeF(charInfoPackage.getMaxHp()); // hp max writeF(charInfoPackage.getMaxMp()); // mp max long deleteTime = charInfoPackage.getDeleteTimer(); int deletedays = 0; if (deleteTime > 0) deletedays = (int)((deleteTime-System.currentTimeMillis())/1000); writeD(deletedays); // days left before // delete .. if != 0 // then char is inactive writeD(charInfoPackage.getClassId()); if (i == _activeId) writeD(0x01); else writeD(0x00); //c3 auto-select char writeC(charInfoPackage.getEnchantEffect() > 127 ? 127 : charInfoPackage.getEnchantEffect()); writeD(charInfoPackage.getAugmentationId()); //writeD(charInfoPackage.getTransformId()); // Used to display Transformations writeD(0x00); // Currently on retail when you are on character select you don't see your transformation. } } private CharSelectInfoPackage[] loadCharacterSelectInfo() { CharSelectInfoPackage charInfopackage; List characterList = new FastList(); Connection con = null; try { con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement statement = con.prepareStatement("SELECT account_name, charId, char_name, level, maxHp, curHp, maxMp, curMp, face, hairStyle, hairColor, sex, heading, x, y, z, exp, sp, karma, pvpkills, pkkills, clanid, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, base_class, transform_id FROM characters WHERE account_name=?"); statement.setString(1, _loginName); ResultSet charList = statement.executeQuery(); while (charList.next())// fills the package { charInfopackage = restoreChar(charList); if ( charInfopackage != null ) characterList.add(charInfopackage); } charList.close(); statement.close(); return characterList.toArray(new CharSelectInfoPackage[characterList.size()]); } catch (Exception e) { _log.log(Level.WARNING, "Could not restore char info: " + e.getMessage(), e); } finally { L2DatabaseFactory.close(con); } return new CharSelectInfoPackage[0]; } private void loadCharacterSubclassInfo(CharSelectInfoPackage charInfopackage, int ObjectId, int activeClassId) { Connection con = null; try { con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement statement = con.prepareStatement("SELECT exp, sp, level FROM character_subclasses WHERE charId=? && class_id=? ORDER BY charId"); statement.setInt(1, ObjectId); statement.setInt(2, activeClassId); ResultSet charList = statement.executeQuery(); if (charList.next()) { charInfopackage.setExp(charList.getLong("exp")); charInfopackage.setSp(charList.getInt("sp")); charInfopackage.setLevel(charList.getInt("level")); } charList.close(); statement.close(); } catch (Exception e) { _log.log(Level.WARNING, "Could not restore char subclass info: " + e.getMessage(), e); } finally { try { L2DatabaseFactory.close(con); } catch (Exception e) {} } } private CharSelectInfoPackage restoreChar(ResultSet chardata) throws Exception { int objectId = chardata.getInt("charId"); String name = chardata.getString("char_name"); // See if the char must be deleted long deletetime = chardata.getLong("deletetime"); if (deletetime > 0) { if (System.currentTimeMillis() > deletetime) { L2Clan clan = ClanTable.getInstance().getClan(chardata.getInt("clanid")); if(clan != null) clan.removeClanMember(objectId, 0); L2GameClient.deleteCharByObjId(objectId); return null; } } CharSelectInfoPackage charInfopackage = new CharSelectInfoPackage(objectId, name); charInfopackage.setLevel(chardata.getInt("level")); charInfopackage.setMaxHp(chardata.getInt("maxhp")); charInfopackage.setCurrentHp(chardata.getDouble("curhp")); charInfopackage.setMaxMp(chardata.getInt("maxmp")); charInfopackage.setCurrentMp(chardata.getDouble("curmp")); charInfopackage.setKarma(chardata.getInt("karma")); charInfopackage.setPkKills(chardata.getInt("pkkills")); charInfopackage.setPvPKills(chardata.getInt("pvpkills")); charInfopackage.setFace(chardata.getInt("face")); charInfopackage.setHairStyle(chardata.getInt("hairstyle")); charInfopackage.setHairColor(chardata.getInt("haircolor")); charInfopackage.setSex(chardata.getInt("sex")); charInfopackage.setExp(chardata.getLong("exp")); charInfopackage.setSp(chardata.getInt("sp")); charInfopackage.setClanId(chardata.getInt("clanid")); charInfopackage.setRace(chardata.getInt("race")); final int baseClassId = chardata.getInt("base_class"); final int activeClassId = chardata.getInt("classid"); charInfopackage.setX(chardata.getInt("x")); charInfopackage.setY(chardata.getInt("y")); charInfopackage.setZ(chardata.getInt("z")); // if is in subclass, load subclass exp, sp, lvl info if(baseClassId != activeClassId) loadCharacterSubclassInfo(charInfopackage, objectId, activeClassId); charInfopackage.setClassId(activeClassId); // Get the augmentation id for equipped weapon int weaponObjId = charInfopackage.getPaperdollObjectId(Inventory.PAPERDOLL_LRHAND); if (weaponObjId < 1) weaponObjId = charInfopackage.getPaperdollObjectId(Inventory.PAPERDOLL_RHAND); // Check Transformation int cursedWeaponId = CursedWeaponsManager.getInstance().checkOwnsWeaponId(objectId); if (cursedWeaponId > 0) { // cursed weapon transformations if(cursedWeaponId == 8190) charInfopackage.setTransformId(301); else if(cursedWeaponId == 8689) charInfopackage.setTransformId(302); else charInfopackage.setTransformId(0); } else if (chardata.getInt("transform_id") > 0) { charInfopackage.setTransformId(chardata.getInt("transform_id")); } else charInfopackage.setTransformId(0); if (weaponObjId > 0) { Connection con = null; try { con = L2DatabaseFactory.getInstance().getConnection(); PreparedStatement statement = con.prepareStatement("SELECT augAttributes FROM item_attributes WHERE itemId=?"); statement.setInt(1, weaponObjId); ResultSet result = statement.executeQuery(); if (result.next()) { int augment = result.getInt("augAttributes"); charInfopackage.setAugmentationId(augment == -1 ? 0 : augment); } result.close(); statement.close(); } catch (Exception e) { _log.log(Level.WARNING, "Could not restore augmentation info: " + e.getMessage(), e); } finally { try { L2DatabaseFactory.close(con); } catch (Exception e) {} } } /* * Check if the base class is set to zero and alse doesn't match * with the current active class, otherwise send the base class ID. * * This prevents chars created before base class was introduced * from being displayed incorrectly. */ if (baseClassId == 0 && activeClassId > 0) charInfopackage.setBaseClassId(activeClassId); else charInfopackage.setBaseClassId(baseClassId); charInfopackage.setDeleteTimer(deletetime); charInfopackage.setLastAccess(chardata.getLong("lastAccess")); return charInfopackage; } @Override public String getType() { return _S__1F_CHARSELECTINFO; } }