Prechádzať zdrojové kódy

BETA: H5 Contact List (Mail) implementation (by mrTJO and me :P)

Rumen Nikiforov 14 rokov pred
rodič
commit
1b211a6620
19 zmenil súbory, kde vykonal 946 pridanie a 9 odobranie
  1. 9 1
      L2J_Server_BETA/java/com/l2jserver/accountmanager/SQLAccountManager.java
  2. 6 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/idfactory/IdFactory.java
  3. 210 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2ContactList.java
  4. 8 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
  5. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/olympiad/OlympiadGameClassed.java
  6. 1 1
      L2J_Server_BETA/java/com/l2jserver/gameserver/model/olympiad/OlympiadGameNonClassed.java
  7. 6 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/L2GameClient.java
  8. 6 6
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/L2GamePacketHandler.java
  9. 49 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/SystemMessageId.java
  10. 2 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java
  11. 61 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExAddContactToContactList.java
  12. 58 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExDeleteContactFromContactList.java
  13. 52 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExFriendListExtended.java
  14. 67 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExOlympiadMatchListRefresh.java
  15. 54 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExShowContactList.java
  16. 57 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExConfirmAddingContact.java
  17. 88 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExOlympiadMatchList.java
  18. 64 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExShowContactList.java
  19. 147 0
      L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/FriendListExtended.java

+ 9 - 1
L2J_Server_BETA/java/com/l2jserver/accountmanager/SQLAccountManager.java

@@ -390,10 +390,18 @@ public class SQLAccountManager
 				statement.setString(1, objIds.get(index));
 				statement.executeUpdate();
 				
+				// contacts
+				statement.close();
+				statement = con.prepareStatement("DELETE FROM character_contacts WHERE charId=? OR contactId=?;");
+				statement.setString(1, objIds.get(index));
+				statement.setString(2, objIds.get(index));
+				statement.executeUpdate();
+				
 				// friends
 				statement.close();
-				statement = con.prepareStatement("DELETE FROM character_friends WHERE charId=?;");
+				statement = con.prepareStatement("DELETE FROM character_friends WHERE charId=? OR friendId=?;");
 				statement.setString(1, objIds.get(index));
+				statement.setString(2, objIds.get(index));
 				statement.executeUpdate();
 				
 				// merchant_lease

+ 6 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/idfactory/IdFactory.java

@@ -39,6 +39,8 @@ public abstract class IdFactory
 		"UPDATE items                 SET owner_id = ?    WHERE owner_id = ?",
 		"UPDATE items                 SET object_id = ?   WHERE object_id = ?",
 		"UPDATE character_quests      SET charId = ?     WHERE charId = ?",
+		"UPDATE character_contacts     SET charId = ?     WHERE charId = ?",
+		"UPDATE character_contacts     SET friendId = ?   WHERE contactId = ?",
 		"UPDATE character_friends     SET charId = ?     WHERE charId = ?",
 		"UPDATE character_friends     SET friendId = ?   WHERE friendId = ?",
 		"UPDATE character_hennas      SET charId = ? WHERE charId = ?",
@@ -75,6 +77,8 @@ public abstract class IdFactory
 		"SELECT owner_id    FROM items                 WHERE object_id >= ?   AND object_id < ?",
 		"SELECT object_id   FROM items                 WHERE object_id >= ?   AND object_id < ?",
 		"SELECT charId     FROM character_quests      WHERE charId >= ?     AND charId < ?",
+		"SELECT charId     FROM character_contacts    WHERE charId >= ?     AND charId < ?",
+		"SELECT contactId  FROM character_contacts    WHERE contactId >= ?  AND contactId < ?",
 		"SELECT charId     FROM character_friends     WHERE charId >= ?     AND charId < ?",
 		"SELECT charId     FROM character_friends     WHERE friendId >= ?   AND friendId < ?",
 		"SELECT charId     FROM character_hennas      WHERE charId >= ? AND charId < ?",
@@ -199,6 +203,8 @@ public abstract class IdFactory
 			// stmt.executeUpdate("DELETE FROM characters WHERE characters.account_name NOT IN (SELECT login FROM accounts);");
 			
 			// If the character does not exist...
+			cleanCount += stmt.executeUpdate("DELETE FROM character_contacts WHERE character_contacts.charId NOT IN (SELECT charId FROM characters);");
+			cleanCount += stmt.executeUpdate("DELETE FROM character_contacts WHERE character_contacts.contactId NOT IN (SELECT charId FROM characters);");
 			cleanCount += stmt.executeUpdate("DELETE FROM character_friends WHERE character_friends.charId NOT IN (SELECT charId FROM characters);");
 			cleanCount += stmt.executeUpdate("DELETE FROM character_friends WHERE character_friends.friendId NOT IN (SELECT charId FROM characters);");
 			cleanCount += stmt.executeUpdate("DELETE FROM character_hennas WHERE character_hennas.charId NOT IN (SELECT charId FROM characters);");

+ 210 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2ContactList.java

@@ -0,0 +1,210 @@
+/*
+ * 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.l2jserver.gameserver.model;
+
+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 javolution.util.FastList;
+
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.datatables.CharNameTable;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.SystemMessageId;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
+
+/**
+ * @author UnAfraid & mrTJO
+ * TODO: System Messages:
+ * 	ADD:
+		3223: The previous name is being registered. Please try again later.
+ *	END OF ADD
+ *	DEL
+ * 		3219: $s1 was successfully deleted from your Contact List.
+		3217: The name is not currently registered.
+	END OF DEL
+ */
+public class L2ContactList
+{
+	private final Logger _log = Logger.getLogger(getClass().getName());
+	private final L2PcInstance activeChar;
+	private final List<String> _contacts;
+	
+	private final String QUERY_ADD = "INSERT INTO character_contacts (charId, contactId) VALUES (?, ?)";
+	private final String QUERY_REMOVE = "DELETE FROM character_contacts WHERE charId = ? and contactId = ?";
+	private final String QUERY_LOAD = "SELECT contactId FROM character_contacts WHERE charId = ?";
+		
+	public L2ContactList(L2PcInstance player)
+	{
+		activeChar = player;
+		_contacts = new FastList<String>().shared();
+		restore();
+	}
+	
+	public void restore()
+	{
+		_contacts.clear();
+		
+		Connection con = null;
+		
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement(QUERY_LOAD);
+			statement.setInt(1, activeChar.getObjectId());
+			ResultSet rset = statement.executeQuery();
+			
+			int contactId;
+			String contactName;
+			while (rset.next())
+			{
+				contactId = rset.getInt(1);
+				contactName = CharNameTable.getInstance().getNameById(contactId);
+				if (contactName == null || contactName == activeChar.getName() || contactId == activeChar.getObjectId())
+					continue;
+				
+				_contacts.add(contactName);
+			}
+			
+			rset.close();
+			statement.close();
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, "Error found in " + activeChar.getName() + "'s ContactsList: " + e.getMessage(), e);
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+	}
+	
+	public boolean add(String name)
+	{
+		SystemMessage sm;
+		
+		int contactId = CharNameTable.getInstance().getIdByName(name);
+		if (_contacts.contains(name))
+		{
+			activeChar.sendPacket(SystemMessageId.NAME_ALREADY_EXIST_ON_CONTACT_LIST);
+			return false;
+		}
+		else if (activeChar.getName() == name)
+		{
+			activeChar.sendPacket(SystemMessageId.CANNOT_ADD_YOUR_NAME_ON_CONTACT_LIST);
+			return false;
+		}
+		else if (_contacts.size() >= 100)
+		{
+			activeChar.sendPacket(SystemMessageId.CONTACT_LIST_LIMIT_REACHED);
+			return false;
+		}
+		else if (contactId < 1)
+		{
+			sm = SystemMessage.getSystemMessage(SystemMessageId.NAME_S1_NOT_EXIST_TRY_ANOTHER_NAME);
+			sm.addString(name);
+			activeChar.sendPacket(sm);
+			return false;
+		}
+		else
+		{
+			for (String contactName : _contacts)
+			{
+				if (contactName.equalsIgnoreCase(name))
+				{
+					activeChar.sendPacket(SystemMessageId.NAME_ALREADY_EXIST_ON_CONTACT_LIST);
+					return false;
+				}
+			}
+		}
+		
+		Connection con = null;
+		try
+		{	
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement(QUERY_ADD);
+			statement.setInt(1, activeChar.getObjectId());
+			statement.setInt(2, contactId);
+			statement.execute();
+			statement.close();
+			
+			_contacts.add(name);
+			
+			sm = SystemMessage.getSystemMessage(SystemMessageId.S1_SUCCESSFULLY_ADDED_TO_CONTACT_LIST);
+			sm.addString(name);
+			activeChar.sendPacket(sm);
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, "Error found in " + activeChar.getName() + "'s ContactsList: " + e.getMessage(), e);
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+		return true;
+	}
+	
+	public void remove(String name)
+	{
+		int contactId = CharNameTable.getInstance().getIdByName(name);
+		
+		if (!_contacts.contains(name))
+		{
+			activeChar.sendPacket(SystemMessageId.NAME_NOT_REGISTERED_ON_CONTACT_LIST);
+			return;
+		}
+		
+		else if (contactId < 1)
+		{
+			//TODO: Message?
+			return;
+		}
+		
+		_contacts.remove(name);
+		
+		Connection con = null;
+		
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement(QUERY_REMOVE);
+			statement.setInt(1, activeChar.getObjectId());
+			statement.setInt(2, contactId);
+			statement.execute();
+			statement.close();
+			SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_SUCCESFULLY_DELETED_FROM_CONTACT_LIST);
+			sm.addString(name);
+			activeChar.sendPacket(sm);
+		}
+		catch (Exception e)
+		{
+			_log.log(Level.WARNING, "Error found in " + activeChar.getName() + "'s ContactsList: " + e.getMessage(), e);
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+	}
+	
+	public List<String> getAllContacts()
+	{
+		return _contacts;
+	}
+}

+ 8 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -98,6 +98,7 @@ import com.l2jserver.gameserver.model.FishData;
 import com.l2jserver.gameserver.model.L2AccessLevel;
 import com.l2jserver.gameserver.model.L2Clan;
 import com.l2jserver.gameserver.model.L2ClanMember;
+import com.l2jserver.gameserver.model.L2ContactList;
 import com.l2jserver.gameserver.model.L2Effect;
 import com.l2jserver.gameserver.model.L2EnchantSkillLearn;
 import com.l2jserver.gameserver.model.L2Fishing;
@@ -453,6 +454,8 @@ public final class L2PcInstance extends L2Playable
 	
 	private boolean _isIn7sDungeon = false;
 	
+	private final L2ContactList _contactList = new L2ContactList(this);
+	
 	private int _bookmarkslot = 0; // The Teleport Bookmark Slot
 	
 	private List<TeleportBookmark> tpbookmark = new FastList<TeleportBookmark>();
@@ -15124,4 +15127,9 @@ public final class L2PcInstance extends L2Playable
 	{
 		return _lastPetitionGmName;
 	}
+	
+	public L2ContactList getContactList()
+	{
+		return _contactList;
+	}
 }

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/olympiad/OlympiadGameClassed.java

@@ -24,7 +24,7 @@ import com.l2jserver.util.Rnd;
  * @author DS
  *
  */
-class OlympiadGameClassed extends OlympiadGameNormal
+public class OlympiadGameClassed extends OlympiadGameNormal
 {
 	private OlympiadGameClassed(int id, Participant[] opponents)
 	{

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/olympiad/OlympiadGameNonClassed.java

@@ -23,7 +23,7 @@ import com.l2jserver.Config;
  * @author DS
  *
  */
-class OlympiadGameNonClassed extends OlympiadGameNormal
+public class OlympiadGameNonClassed extends OlympiadGameNormal
 {
 	private OlympiadGameNonClassed(int id, Participant[] opponents)
 	{

+ 6 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/L2GameClient.java

@@ -425,6 +425,12 @@ public final class L2GameClient extends MMOClient<MMOConnection<L2GameClient>> i
 			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement ;
 			
+			statement = con.prepareStatement("DELETE FROM character_friends WHERE charId=? OR contactId=?");
+			statement.setInt(1, objid);
+			statement.setInt(2, objid);
+			statement.execute();
+			statement.close();
+			
 			statement = con.prepareStatement("DELETE FROM character_friends WHERE charId=? OR friendId=?");
 			statement.setInt(1, objid);
 			statement.setInt(2, objid);

+ 6 - 6
L2J_Server_BETA/java/com/l2jserver/gameserver/network/L2GamePacketHandler.java

@@ -562,7 +562,7 @@ public final class L2GamePacketHandler implements IPacketHandler<L2GameClient>,
 						//msg = new RequestPackageSendableItemList();
 						break;
 					case 0xa8:
-						// msg = new RequestPackageSend();
+						//msg = new RequestPackageSend();
 						break;
 					case 0xa9:
 						msg = new RequestBlock();
@@ -1075,19 +1075,19 @@ public final class L2GamePacketHandler implements IPacketHandler<L2GameClient>,
 								msg = new RequestVoteNew();
 								break;
 							case 0x84:
-								// RequestExAddPostFriendForPostBox
+								msg = new RequestExAddContactToContactList();
 								break;
 							case 0x85:
-								// RequestExDeletePostFriendForPostBox
+								msg = new RequestExDeleteContactFromContactList();
 								break;
 							case 0x86:
-								// RequestExShowPostFriendListForPostBox
+								msg = new RequestExShowContactList();
 								break;
 							case 0x87:
-								// RequestExFriendListForPostBox
+								msg = new RequestExFriendListExtended();
 								break;
 							case 0x88:
-								// - 
+								//msg = new RequestExOlympiadMatchListRefresh();
 								break;
 							case 0x89:
 								// RequestBRGamePoint

+ 49 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/SystemMessageId.java

@@ -14668,6 +14668,48 @@ public final class SystemMessageId
 	 */
 	public static final SystemMessageId YOU_OBTAINED_S1_RECOMMENDATIONS;
 	
+	/**
+	 * ID: 3214<br>
+	 * Message: $s1 was successfully added to your Contact List.
+	 */
+	public static final SystemMessageId S1_SUCCESSFULLY_ADDED_TO_CONTACT_LIST;
+	
+	/**
+	 * ID: 3215<br>
+	 * Message: The name $s1% doesn't exist. Please try another name.
+	 */
+	public static final SystemMessageId NAME_S1_NOT_EXIST_TRY_ANOTHER_NAME;
+	
+	/**
+	 * ID: 3216<br>
+	 * Message: The name already exists on the added list.
+	 */
+	public static final SystemMessageId NAME_ALREADY_EXIST_ON_CONTACT_LIST;
+	
+	/**
+	 * ID: 3217<br>
+	 * Message: The name is not currently registered.
+	 */
+	public static final SystemMessageId NAME_NOT_REGISTERED_ON_CONTACT_LIST;
+	
+	/**
+	 * ID: 3219<br>
+	 * Message: $s1 was successfully deleted from your Contact List.
+	 */
+	public static final SystemMessageId S1_SUCCESFULLY_DELETED_FROM_CONTACT_LIST;
+	
+	/**
+	 * ID: 3221<br>
+	 * Message: You cannot add your own name.
+	 */
+	public static final SystemMessageId CANNOT_ADD_YOUR_NAME_ON_CONTACT_LIST;
+	
+	/**
+	 * ID: 3222<br>
+	 * Message: The maximum number of names (100) has been reached. You cannot register any more.
+	 */
+	public static final SystemMessageId CONTACT_LIST_LIMIT_REACHED;
+	
 	/**
 	 * ID: 3255<br>
 	 * Message: Arcane Shield decreased your MP by $1 instead of HP.
@@ -17124,6 +17166,13 @@ public final class SystemMessageId
 		C1_IS_SET_TO_REFUSE_DUEL_REQUEST = new SystemMessageId(3169);
 		YOU_CURRENTLY_DO_NOT_HAVE_ANY_RECOMMENDATIONS = new SystemMessageId(3206);
 		YOU_OBTAINED_S1_RECOMMENDATIONS = new SystemMessageId(3207);
+		S1_SUCCESSFULLY_ADDED_TO_CONTACT_LIST = new SystemMessageId(3214);
+		NAME_S1_NOT_EXIST_TRY_ANOTHER_NAME = new SystemMessageId(3215);
+		NAME_ALREADY_EXIST_ON_CONTACT_LIST = new SystemMessageId(3216);
+		NAME_NOT_REGISTERED_ON_CONTACT_LIST = new SystemMessageId(3217);
+		S1_SUCCESFULLY_DELETED_FROM_CONTACT_LIST = new SystemMessageId(3219);
+		CANNOT_ADD_YOUR_NAME_ON_CONTACT_LIST = new SystemMessageId(3221);
+		CONTACT_LIST_LIMIT_REACHED = new SystemMessageId(3222);
 		ARCANE_SHIELD_DECREASED_YOUR_MP_BY_S1_INSTEAD_OF_HP = new SystemMessageId(3255);
 		MP_BECAME_0_ARCANE_SHIELD_DISAPPEARING = new SystemMessageId(3256);
 		YOU_CANNOT_BOOKMARK_THIS_LOCATION_BECAUSE_YOU_DO_NOT_HAVE_A_MY_TELEPORT_FLAG = new SystemMessageId(6501);

+ 2 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/EnterWorld.java

@@ -71,6 +71,7 @@ import com.l2jserver.gameserver.network.serverpackets.ExNavitAdventPointInfoPack
 import com.l2jserver.gameserver.network.serverpackets.ExNavitAdventTimeChange;
 import com.l2jserver.gameserver.network.serverpackets.ExNoticePostArrived;
 import com.l2jserver.gameserver.network.serverpackets.ExNotifyPremiumItem;
+import com.l2jserver.gameserver.network.serverpackets.ExShowContactList;
 import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
 import com.l2jserver.gameserver.network.serverpackets.ExStorageMaxCount;
 import com.l2jserver.gameserver.network.serverpackets.ExVoteSystemInfo;
@@ -419,6 +420,7 @@ public class EnterWorld extends L2GameClientPacket
 		sendPacket(new ExVoteSystemInfo(activeChar));
 		sendPacket(new ExNavitAdventPointInfoPacket(0));
 		sendPacket(new ExNavitAdventTimeChange(-1)); // only set pause state...
+		sendPacket(new ExShowContactList(activeChar));
 		
 		for (L2ItemInstance i : activeChar.getInventory().getItems())
 		{

+ 61 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExAddContactToContactList.java

@@ -0,0 +1,61 @@
+/*
+ * 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.l2jserver.gameserver.network.clientpackets;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.ExConfirmAddingContact;
+
+/**
+ * Format: (ch)S
+ * S: Character Name
+ * 
+ * @author UnAfraid & mrTJO
+ */
+public class RequestExAddContactToContactList extends L2GameClientPacket
+{
+	private static final String _C__D0_84_REQUESTEXADDCONTACTTOCONTACTLIST = "[C] D0:84 RequestExAddContactToContactList";
+	private String _name;
+	
+	@Override
+	protected void readImpl()
+	{
+		_name = readS();
+	}
+
+	@Override
+	protected void runImpl()
+	{
+		if (!Config.ALLOW_MAIL)
+			return;
+		
+		if (_name == null)
+			return;
+		
+		final L2PcInstance activeChar = getClient().getActiveChar();
+		if (activeChar == null)
+			return;
+		
+		boolean charAdded = activeChar.getContactList().add(_name);
+		activeChar.sendPacket(new ExConfirmAddingContact(_name, charAdded));
+	}
+
+	
+	@Override
+	public String getType()
+	{
+		return _C__D0_84_REQUESTEXADDCONTACTTOCONTACTLIST;
+	}	
+}

+ 58 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExDeleteContactFromContactList.java

@@ -0,0 +1,58 @@
+/*
+ * 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.l2jserver.gameserver.network.clientpackets;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * Format: (ch)S
+ * S: Character Name
+ * 
+ * @author UnAfraid & mrTJO
+ */
+public class RequestExDeleteContactFromContactList extends L2GameClientPacket
+{
+	private static final String _C__D0_85_REQUESTEXDELETECONTACTFROMCONTACTLIST = "[C] D0:85 RequestExDeleteContactFromContactList";
+	private String _name;
+	
+	@Override
+	protected void readImpl()
+	{
+		_name = readS();
+	}
+	
+	@Override
+	protected void runImpl()
+	{
+		if (!Config.ALLOW_MAIL)
+			return;
+		
+		if (_name == null)
+			return;
+		
+		final L2PcInstance activeChar = getClient().getActiveChar();
+		if (activeChar == null)
+			return;
+		
+		activeChar.getContactList().remove(_name);
+	}
+	
+	@Override
+	public String getType()
+	{
+		return _C__D0_85_REQUESTEXDELETECONTACTFROMCONTACTLIST;
+	}	
+}

+ 52 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExFriendListExtended.java

@@ -0,0 +1,52 @@
+/*
+ * 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.l2jserver.gameserver.network.clientpackets;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.FriendListExtended;
+
+/**
+ * @author mrTJO & UnAfraid
+ */
+public final class RequestExFriendListExtended extends L2GameClientPacket
+{
+	private static final String _C__D0_87_REQUESTEXFRIENDLISTEXTENDED = "[C] D0:87 RequestExFriendListExtended";
+	
+	@Override
+	protected void readImpl()
+	{
+		// trigger packet
+	}
+	
+	@Override
+	public void runImpl()
+	{
+		if (!Config.ALLOW_MAIL)
+			return;
+		
+		final L2PcInstance activeChar = getClient().getActiveChar();
+		if (activeChar == null)
+			return;
+		
+		activeChar.sendPacket(new FriendListExtended(activeChar));
+	}
+	
+	@Override
+	public String getType()
+	{
+		return _C__D0_87_REQUESTEXFRIENDLISTEXTENDED;
+	}
+}

+ 67 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExOlympiadMatchListRefresh.java

@@ -0,0 +1,67 @@
+/*
+ * 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.l2jserver.gameserver.network.clientpackets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.olympiad.OlympiadGameManager;
+import com.l2jserver.gameserver.model.olympiad.OlympiadGameTask;
+import com.l2jserver.gameserver.network.serverpackets.ExOlympiadMatchList;
+
+/**
+ * Format: (ch)d
+ * d: unknown (always 0?)
+ * 
+ * @author  mrTJO
+ */
+public class RequestExOlympiadMatchListRefresh extends L2GameClientPacket
+{
+	private static final String _C__D0_88_REQUESTEXOLYMPIADMATCHLISTREFRESH = "[C] D0:88 RequestExOlympiadMatchListRefresh";
+	
+	@Override
+	protected void readImpl()
+	{
+		// readD();
+	}
+	
+	@Override
+	protected void runImpl()
+	{
+		final L2PcInstance activeChar = getClient().getActiveChar();
+		if (activeChar == null || !activeChar.inObserverMode())
+			return;
+		
+		List<OlympiadGameTask> games = new ArrayList<OlympiadGameTask>();
+		OlympiadGameTask task;
+		for (int i = 0; i < OlympiadGameManager.getInstance().getNumberOfStadiums(); i++)
+		{
+			task = OlympiadGameManager.getInstance().getOlympiadTask(i);
+			if (task != null)
+			{
+				if (!task.isBattleFinished())
+					games.add(task);
+			}
+		}
+		activeChar.sendPacket(new ExOlympiadMatchList(games));
+	}
+	
+	@Override
+	public String getType()
+	{
+		return _C__D0_88_REQUESTEXOLYMPIADMATCHLISTREFRESH;
+	}
+}

+ 54 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestExShowContactList.java

@@ -0,0 +1,54 @@
+/*
+ * 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.l2jserver.gameserver.network.clientpackets;
+
+import com.l2jserver.Config;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.network.serverpackets.ExShowContactList;
+
+/**
+ * Format: (ch)
+ * 
+ * @author mrTJO & UnAfraid
+ */
+public final class RequestExShowContactList extends L2GameClientPacket
+{
+	private static final String _C__D0_86_REQUESTEXSHOWCONTACTLIST = "[C] D0:86 RequestExShowContactList";
+	
+	@Override
+	protected void readImpl()
+	{
+		// trigger packet
+	}
+	
+	@Override
+	public void runImpl()
+	{
+		if (!Config.ALLOW_MAIL)
+			return;
+		
+		final L2PcInstance activeChar = getClient().getActiveChar();
+		if (activeChar == null)
+			return;
+		
+		activeChar.sendPacket(new ExShowContactList(activeChar));
+	}
+	
+	@Override
+	public String getType()
+	{
+		return _C__D0_86_REQUESTEXSHOWCONTACTLIST;
+	}
+}

+ 57 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExConfirmAddingContact.java

@@ -0,0 +1,57 @@
+/*
+ * 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.l2jserver.gameserver.network.serverpackets;
+
+/**
+ * Format: (ch)Sd
+ * S: Character Name
+ * d: Status
+ * 
+ * @author mrTJO & UnAfraid
+ */
+public class ExConfirmAddingContact extends L2GameServerPacket
+{
+	private static final String _S__FE_D2_EXCONFIRMADDINGCONTACT = "[S] FE:D2 ExConfirmAddingContact";
+	private final String _charName;
+	private final boolean _added;
+	
+	public ExConfirmAddingContact(String charName, boolean added)
+	{
+		_charName = charName;
+		_added = added;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket#writeImpl()
+	 */
+	@Override
+	protected void writeImpl()
+	{
+		writeC(0xFE);
+		writeH(0xD2);
+		writeS(_charName);
+		writeD(_added ? 0x01 : 0x00);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket#getType()
+	 */
+	@Override
+	public String getType()
+	{
+		return _S__FE_D2_EXCONFIRMADDINGCONTACT;
+	}
+	
+}

+ 88 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExOlympiadMatchList.java

@@ -0,0 +1,88 @@
+/*
+ * 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.l2jserver.gameserver.network.serverpackets;
+ 
+import java.util.List;
+
+import com.l2jserver.gameserver.model.olympiad.OlympiadGameClassed;
+import com.l2jserver.gameserver.model.olympiad.OlympiadGameNonClassed;
+import com.l2jserver.gameserver.model.olympiad.OlympiadGameTask;
+import com.l2jserver.gameserver.model.olympiad.OlympiadGameTeams;
+ 
+/**
+ * Format: (chd) ddd[dddS]
+ * d: number of matches
+ * d: unknown (always 0)
+ * [
+ *  d: arena
+ *  d: match type
+ *  d: status
+ *  S: player 1 name
+ *  S: player 2 name
+ * ]
+ * 
+ * @author mrTJO
+ */
+public class ExOlympiadMatchList extends L2GameServerPacket
+{
+	private static final String _S__FE_D4_OLYMPIADMATCHLIST = "[S] FE:D4 ExOlympiadMatchList";
+	private final List<OlympiadGameTask> _games;
+	
+	/**
+	 * @param games: competitions list
+	 */
+	public ExOlympiadMatchList(List<OlympiadGameTask> games)
+	{
+		_games = games;
+	}
+	
+	@Override
+	protected final void writeImpl()
+	{
+		writeC(0xfe);
+		writeH(0xd4);
+		writeD(0x00);
+		
+		writeD(_games.size());
+		writeD(0x00);
+		
+		for (OlympiadGameTask curGame : _games)
+		{
+			writeD(curGame.getGame().getStadiumId()); // Stadium Id (Arena 1 = 0)
+			
+			if (curGame.getGame() instanceof OlympiadGameNonClassed)
+				writeD(1);
+			else if (curGame.getGame() instanceof OlympiadGameClassed)
+				writeD(2);
+			else if (curGame.getGame() instanceof OlympiadGameTeams)
+				writeD(-1);
+			else
+				writeD(0);
+			
+			writeD(curGame.isRunning() ? 0x02 : 0x01); // (1 = Standby, 2 = Playing)
+			writeS(curGame.getGame().getPlayerNames()[0]); // Player 1 Name
+			writeS(curGame.getGame().getPlayerNames()[1]); // Player 2 Name
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.l2jserver.gameserver.serverpackets.ServerBasePacket#getType()
+	 */
+	@Override
+	public String getType()
+	{
+		return _S__FE_D4_OLYMPIADMATCHLIST;
+	}
+}

+ 64 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/ExShowContactList.java

@@ -0,0 +1,64 @@
+/*
+ * 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.l2jserver.gameserver.network.serverpackets;
+
+import java.util.List;
+
+import javolution.util.FastList;
+
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * Format: (ch)d[S]
+ * d: Number of Contacts
+ * [
+ * 	S: Character Name
+ * ]
+ * 
+ * @author UnAfraid & mrTJO
+ */
+public class ExShowContactList extends L2GameServerPacket
+{
+	private static final String _S__FE_D3_EXSHOWCONTACTLIST = "[S] FE:D3 ExShowContactList";
+	private final List<String> _contacts;
+	
+	public ExShowContactList(L2PcInstance player)
+	{
+		_contacts = new FastList<String>();
+		_contacts.addAll(player.getContactList().getAllContacts());
+	}
+	
+	@Override
+	protected void writeImpl()
+	{
+		if (_contacts.size() < 1)
+			return;
+		
+		writeC(0xFE);
+		writeH(0xD3);
+		writeD(_contacts.size());
+		for (String name : _contacts)
+		{
+			writeS(name);
+		}
+	}
+	
+	@Override
+	public String getType()
+	{
+		return _S__FE_D3_EXSHOWCONTACTLIST;
+	}
+	
+}

+ 147 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/FriendListExtended.java

@@ -0,0 +1,147 @@
+/*
+ * 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.l2jserver.gameserver.network.serverpackets;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.List;
+
+import javolution.util.FastList;
+
+import com.l2jserver.L2DatabaseFactory;
+import com.l2jserver.gameserver.datatables.CharNameTable;
+import com.l2jserver.gameserver.model.L2World;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * Support for "Chat with Friends" dialog.
+ *
+ * This packet is sent only at login.
+ *
+ * Format: (c) d[dSdddd]
+ * d: Total Friend Count
+ *
+ * d: Friend ID
+ * S: Friend Name
+ * d: Online/Offline
+ * d: Player Object Id (0 if offline)
+ * d: Player Class Id
+ * d: Player Level
+ *
+ * @author mrTJO & UnAfraid
+ * 
+ */
+public class FriendListExtended extends L2GameServerPacket
+{
+	// private static Logger _log = Logger.getLogger(FriendList.class.getName());
+	private static final String _S__FA_FRIENDLISTEXTENDED = "[S] 75 FriendListExtended";
+	private final List<FriendInfo> _info;
+	
+	private static class FriendInfo
+	{
+		int objId;
+		String name;
+		boolean online;
+		int classid;
+		int level;
+		
+		public FriendInfo(int objId, String name, boolean online, int classid, int level)
+		{
+			this.objId = objId;
+			this.name = name;
+			this.online = online;
+			this.classid = classid;
+			this.level = level;
+		}
+	}
+	
+	public FriendListExtended(L2PcInstance player)
+	{
+		_info = new FastList<FriendInfo>(player.getFriendList().size());
+		for (int objId : player.getFriendList())
+		{
+			String name = CharNameTable.getInstance().getNameById(objId);
+			L2PcInstance player1 = L2World.getInstance().getPlayer(objId);
+			
+			boolean online = false;
+			int classid = 0;
+			int level = 0;
+			
+			if (player1 == null)
+			{
+				Connection con = null;
+				try
+				{
+					con = L2DatabaseFactory.getInstance().getConnection();
+					PreparedStatement statement = con.prepareStatement("SELECT char_name, online, classid, level FROM characters WHERE charId = ?");
+					statement.setInt(1, objId);
+					ResultSet rset = statement.executeQuery();
+					if (rset.next())
+					{
+						_info.add(new FriendInfo(objId, rset.getString(1), rset.getInt(2) == 1, rset.getInt(3), rset.getInt(4)));
+					}
+					else
+						continue;
+				}
+				catch (Exception e)
+				{
+					// Who cares?
+				}
+				finally
+				{
+					L2DatabaseFactory.close(con);
+				}
+				
+				continue;
+			}
+			
+			if (player1.isOnline())
+				online = true;
+			
+			classid = player1.getClassId().getId();
+			level = player1.getLevel();
+			
+			_info.add(new FriendInfo(objId, name, online, classid, level));
+		}
+	}
+	
+	@Override
+	protected final void writeImpl()
+	{
+		writeC(0x58);
+		writeD(_info.size());
+		for (FriendInfo info : _info)
+		{
+			writeD(info.objId); // character id
+			writeS(info.name);
+			writeD(info.online ? 0x01 : 0x00); // online
+			writeD(info.online ? info.objId : 0x00); // object id if online
+			writeD(info.classid);
+			writeD(info.level);
+		}
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.l2jserver.gameserver.serverpackets.ServerBasePacket#getType()
+	 */
+	@Override
+	public String getType()
+	{
+		return _S__FA_FRIENDLISTEXTENDED;
+	}
+}