Jelajahi Sumber

BETA: H5 ServerList update by mrTJO

Rumen Nikiforov 14 tahun lalu
induk
melakukan
35d8efa753

+ 55 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/LoginServerThread.java

@@ -26,6 +26,11 @@ import java.security.KeyFactory;
 import java.security.interfaces.RSAPublicKey;
 import java.security.spec.RSAKeyGenParameterSpec;
 import java.security.spec.RSAPublicKeySpec;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -37,6 +42,7 @@ import javolution.util.FastList;
 import javolution.util.FastMap;
 
 import com.l2jserver.Config;
+import com.l2jserver.L2DatabaseFactory;
 import com.l2jserver.gameserver.model.L2World;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.network.L2GameClient;
@@ -49,12 +55,14 @@ import com.l2jserver.gameserver.network.gameserverpackets.PlayerAuthRequest;
 import com.l2jserver.gameserver.network.gameserverpackets.PlayerInGame;
 import com.l2jserver.gameserver.network.gameserverpackets.PlayerLogout;
 import com.l2jserver.gameserver.network.gameserverpackets.PlayerTracert;
+import com.l2jserver.gameserver.network.gameserverpackets.ReplyCharacters;
 import com.l2jserver.gameserver.network.gameserverpackets.ServerStatus;
 import com.l2jserver.gameserver.network.loginserverpackets.AuthResponse;
 import com.l2jserver.gameserver.network.loginserverpackets.InitLS;
 import com.l2jserver.gameserver.network.loginserverpackets.KickPlayer;
 import com.l2jserver.gameserver.network.loginserverpackets.LoginServerFail;
 import com.l2jserver.gameserver.network.loginserverpackets.PlayerAuthResponse;
+import com.l2jserver.gameserver.network.loginserverpackets.RequestCharacters;
 import com.l2jserver.gameserver.network.serverpackets.CharSelectionInfo;
 import com.l2jserver.gameserver.network.serverpackets.LoginFail;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
@@ -68,7 +76,7 @@ public class LoginServerThread extends Thread
 	protected static final Logger _logAccounting = Logger.getLogger("accounting");
 	
 	/** {@see com.l2jserver.loginserver.LoginServer#PROTOCOL_REV } */
-	private static final int REVISION = 0x0104;
+	private static final int REVISION = 0x0105;
 	private RSAPublicKey _publicKey;
 	private String _hostname;
 	private int _port;
@@ -334,6 +342,10 @@ public class LoginServerThread extends Thread
 							KickPlayer kp = new KickPlayer(decrypt);
 							doKickPlayer(kp.getAccount());
 							break;
+						case 0x05:
+							RequestCharacters rc = new RequestCharacters(decrypt);
+							getCharsOnServer(rc.getAccount());
+							break;
 					}
 				}
 			}
@@ -482,7 +494,48 @@ public class LoginServerThread extends Thread
 		}
 	}
 	
-	
+	private void getCharsOnServer(String account)
+	{
+		Connection con = null;
+		int chars = 0;
+		List<Long> charToDel = new ArrayList<Long>();
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement statement = con.prepareStatement("SELECT deletetime FROM characters WHERE account_name=?");
+			statement.setString(1, account);
+			ResultSet rset = statement.executeQuery();
+			while (rset.next())
+			{
+				chars++;
+				long delTime = rset.getLong("deletetime");
+				if (delTime != 0)
+					charToDel.add(delTime);
+			}
+			rset.close();
+			statement.close();
+		}
+		catch (SQLException e)
+		{
+			_log.log(Level.WARNING, "Exception: getCharsOnServer: " + e.getMessage(), e);
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+		
+		ReplyCharacters rec = new ReplyCharacters(account, chars, charToDel);
+		try
+		{
+			sendPacket(rec);
+		}
+		catch (IOException e)
+		{
+			if (Config.DEBUG)
+				_log.log(Level.WARNING, "", e);
+		}
+		
+	}
 	
 	/**
 	 * @param sl

+ 47 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/gameserverpackets/ReplyCharacters.java

@@ -0,0 +1,47 @@
+/*
+ * 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.gameserverpackets;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.l2jserver.util.network.BaseSendablePacket;
+
+/**
+ * @author mrTJO
+ * Thanks to mochitto
+ */
+public class ReplyCharacters extends BaseSendablePacket
+{
+	
+	public ReplyCharacters(String account, int chars, List<Long> timeToDel)
+	{
+		writeC(0x08);
+		writeS(account);
+		writeC(chars);
+		writeC(timeToDel.size());
+		for (long time : timeToDel)
+		{
+			writeQ(time);
+		}
+	}
+	
+	@Override
+	public byte[] getContent() throws IOException
+	{
+		return getBytes();
+	}
+	
+}

+ 40 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/network/loginserverpackets/RequestCharacters.java

@@ -0,0 +1,40 @@
+/*
+ * 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.loginserverpackets;
+
+import com.l2jserver.util.network.BaseRecievePacket;
+
+/**
+ * @author mrTJO
+ * Thanks to mochitto
+ */
+public class RequestCharacters extends BaseRecievePacket
+{
+	private String _account;
+	
+	public RequestCharacters(byte[] decrypt)
+	{
+		super(decrypt);
+		_account = readS();
+	}
+	
+	/**
+	 * @return Return account name
+	 */
+	public String getAccount()
+	{
+		return _account;
+	}
+}

+ 40 - 8
L2J_Server_BETA/java/com/l2jserver/loginserver/GameServerThread.java

@@ -38,12 +38,14 @@ import com.l2jserver.loginserver.gameserverpackets.PlayerAuthRequest;
 import com.l2jserver.loginserver.gameserverpackets.PlayerInGame;
 import com.l2jserver.loginserver.gameserverpackets.PlayerLogout;
 import com.l2jserver.loginserver.gameserverpackets.PlayerTracert;
+import com.l2jserver.loginserver.gameserverpackets.ReplyCharacters;
 import com.l2jserver.loginserver.gameserverpackets.ServerStatus;
 import com.l2jserver.loginserver.loginserverpackets.AuthResponse;
 import com.l2jserver.loginserver.loginserverpackets.InitLS;
 import com.l2jserver.loginserver.loginserverpackets.KickPlayer;
 import com.l2jserver.loginserver.loginserverpackets.LoginServerFail;
 import com.l2jserver.loginserver.loginserverpackets.PlayerAuthResponse;
+import com.l2jserver.loginserver.loginserverpackets.RequestCharacters;
 import com.l2jserver.util.Util;
 import com.l2jserver.util.crypt.NewCrypt;
 import com.l2jserver.util.network.BaseSendablePacket;
@@ -142,30 +144,33 @@ public class GameServerThread extends Thread
 				int packetType = data[0] & 0xff;
 				switch (packetType)
 				{
-					case 00:
+					case 0x00:
 						onReceiveBlowfishKey(data);
 						break;
-					case 01:
+					case 0x01:
 						onGameServerAuth(data);
 						break;
-					case 02:
+					case 0x02:
 						onReceivePlayerInGame(data);
 						break;
-					case 03:
+					case 0x03:
 						onReceivePlayerLogOut(data);
 						break;
-					case 04:
+					case 0x04:
 						onReceiveChangeAccessLevel(data);
 						break;
-					case 05:
+					case 0x05:
 						onReceivePlayerAuthRequest(data);
 						break;
-					case 06:
+					case 0x06:
 						onReceiveServerStatus(data);
 						break;
-					case 07:
+					case 0x07:
 						onReceivePlayerTracert(data);
 						break;
+					case 0x08:
+						onReceivePlayerOnServer(data);
+						break;
 					default:
 						_log.warning("Unknown Opcode ("+Integer.toHexString(packetType).toUpperCase()+") from GameServer, closing connection.");
 						forceClose(LoginServerFail.NOT_AUTHED);
@@ -362,6 +367,20 @@ public class GameServerThread extends Thread
 		}
 	}
 	
+	private void onReceivePlayerOnServer(byte[] data)
+	{
+		if (isAuthed())
+		{
+			ReplyCharacters rec = new ReplyCharacters(data);
+			LoginController.getInstance().setCharactersOnServer(rec.getAccountName(),
+					rec.getCharsOnServer(), rec.getTimeToDelForChars(), getServerId());
+		}
+		else
+		{
+			forceClose(LoginServerFail.NOT_AUTHED);
+		}
+	}
+	
 	private void handleRegProcess(GameServerAuth gameServerAuth)
 	{
 		GameServerTable gameServerTable = GameServerTable.getInstance();
@@ -658,6 +677,19 @@ public class GameServerThread extends Thread
 		}
 	}
 	
+	public void requestCharacters(String account)
+	{
+		RequestCharacters rc = new RequestCharacters(account);
+		try
+		{
+			sendPacket(rc);
+		}
+		catch (IOException e)
+		{
+			e.printStackTrace();
+		}
+	}
+	
 	/**
 	 * @param gameHost The gameHost to set.
 	 */

+ 28 - 0
L2J_Server_BETA/java/com/l2jserver/loginserver/L2LoginClient.java

@@ -18,6 +18,8 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.security.interfaces.RSAPrivateKey;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.logging.Logger;
 
 import org.mmocore.network.MMOClient;
@@ -58,6 +60,8 @@ public final class L2LoginClient extends MMOClient<MMOConnection<L2LoginClient>>
 	private SessionKey _sessionKey;
 	private int _sessionId;
 	private boolean _joinedGS;
+	private Map<Integer, Integer> _charsOnServers;
+	private Map<Integer, long[]> _charsToDelete;
 	
 	private long _connectionStartTime;
 	
@@ -231,6 +235,30 @@ public final class L2LoginClient extends MMOClient<MMOConnection<L2LoginClient>>
 		getConnection().close(lsp);
 	}
 	
+	public void setCharsOnServ(int servId, int chars)
+	{
+		if (_charsOnServers == null)
+			_charsOnServers = new HashMap<Integer, Integer>();
+		_charsOnServers.put(servId, chars);
+	}
+	
+	public Map<Integer, Integer> getCharsOnServ()
+	{
+		return _charsOnServers;
+	}
+	
+	public void serCharsWaitingDelOnServ(int servId, long[] charsToDel)
+	{
+		if (_charsToDelete == null)
+			_charsToDelete = new HashMap<Integer, long[]>();
+		_charsToDelete.put(servId, charsToDel);
+	}
+	
+	public Map<Integer, long[]> getCharsWaitingDelOnServ()
+	{
+		return _charsToDelete;
+	}
+	
 	@Override
 	public void onDisconnection()
 	{

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/loginserver/L2LoginServer.java

@@ -43,7 +43,7 @@ import com.l2jserver.status.Status;
  */
 public class L2LoginServer
 {
-	public static final int PROTOCOL_REV = 0x0104;
+	public static final int PROTOCOL_REV = 0x0105;
 	
 	private static L2LoginServer _instance;
 	private Logger _log = Logger.getLogger(L2LoginServer.class.getName());

+ 20 - 0
L2J_Server_BETA/java/com/l2jserver/loginserver/LoginController.java

@@ -366,6 +366,16 @@ public class LoginController
 		return total;
 	}
 	
+	public void getCharactersOnAccount(String account)
+	{
+		Collection<GameServerInfo> serverList = GameServerTable.getInstance().getRegisteredGameServers().values();
+		for (GameServerInfo gsi : serverList)
+		{
+			if (gsi.isAuthed())
+				gsi.getGameServerThread().requestCharacters(account);
+		}
+	}
+	
 	public int getMaxAllowedOnlinePlayers(int id)
 	{
 		GameServerInfo gsi = GameServerTable.getInstance().getRegisteredGameServerById(id);
@@ -485,6 +495,16 @@ public class LoginController
 		}
 	}
 	
+	public void setCharactersOnServer(String account, int charsNum, long[] timeToDel, int serverId)
+	{
+		L2LoginClient client = _loginServerClients.get(account);
+		if (charsNum > 0)
+			client.setCharsOnServ(serverId, charsNum);
+		
+		if (timeToDel.length > 0)
+			client.serCharsWaitingDelOnServ(serverId, timeToDel);
+	}
+	
 	public boolean isGM(String user)
 	{
 		boolean ok = false;

+ 1 - 0
L2J_Server_BETA/java/com/l2jserver/loginserver/clientpackets/RequestAuthLogin.java

@@ -119,6 +119,7 @@ public class RequestAuthLogin extends L2LoginClientPacket
 			{
 				case AUTH_SUCCESS:
 					client.setAccount(_user);
+					lc.getCharactersOnAccount(_user);
 					client.setState(LoginClientState.AUTHED_LOGIN);
 					client.setSessionKey(lc.assignSessionKeyToClient(_user, client));
 					if (Config.SHOW_LICENCE)

+ 75 - 0
L2J_Server_BETA/java/com/l2jserver/loginserver/gameserverpackets/ReplyCharacters.java

@@ -0,0 +1,75 @@
+/*
+ * 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.loginserver.gameserverpackets;
+
+import com.l2jserver.util.network.BaseRecievePacket;
+
+/**
+ * @author mrTJO
+ * Thanks to mochitto
+ */
+public class ReplyCharacters extends BaseRecievePacket
+{
+	String _account;
+	int _chars;
+	long[] _charsList;
+	/**
+	 * @param decrypt
+	 */
+	public ReplyCharacters(byte[] decrypt)
+	{
+		super(decrypt);
+		_account = readS();
+		_chars = readC();
+		int charsToDel = readC();
+		_charsList = new long[charsToDel];
+		for (int i = 0; i < charsToDel; i++)
+		{
+			_charsList[i] = readQ();
+		}
+	}
+	
+	/**
+	 * @return Account Name
+	 */
+	public String getAccountName()
+	{
+		return _account;
+	}
+	
+	/**
+	 * @return Number of Characters on Server
+	 */
+	public int getCharsOnServer()
+	{
+		return _chars;
+	}
+	
+	/**
+	 * @return Number of Characters on Server Waiting for Delete
+	 */
+	public int getCharsWaitingDel()
+	{
+		return _charsList.length;
+	}
+	
+	/**
+	 * @return Array with Time to Character Delete
+	 */
+	public long[] getTimeToDelForChars()
+	{
+		return _charsList;
+	}
+}

+ 42 - 0
L2J_Server_BETA/java/com/l2jserver/loginserver/loginserverpackets/RequestCharacters.java

@@ -0,0 +1,42 @@
+/*
+ * 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.loginserver.loginserverpackets;
+
+import java.io.IOException;
+
+import com.l2jserver.util.network.BaseSendablePacket;
+
+/**
+ * @author mrTJO
+ * Thanks to mochitto
+ */
+public class RequestCharacters extends BaseSendablePacket
+{
+	public RequestCharacters(String account)
+	{
+		writeC(0x05);
+		writeS(account);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.l2jserver.util.network.BaseSendablePacket#getContent()
+	 */
+	@Override
+	public byte[] getContent() throws IOException
+	{
+		return getBytes();
+	}
+	
+}

+ 27 - 0
L2J_Server_BETA/java/com/l2jserver/loginserver/serverpackets/ServerList.java

@@ -18,6 +18,7 @@ import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import com.l2jserver.loginserver.GameServerTable;
 import com.l2jserver.loginserver.GameServerTable.GameServerInfo;
@@ -53,6 +54,8 @@ public final class ServerList extends L2LoginServerPacket
 {
 	private List<ServerData> _servers;
 	private int _lastServer;
+	private Map<Integer, Integer> _charsOnServers;
+	private Map<Integer, long[]> _charsToDelete;
 	
 	class ServerData
 	{
@@ -103,6 +106,8 @@ public final class ServerList extends L2LoginServerPacket
 		_lastServer = client.getLastServer();
 		for (GameServerInfo gsi : GameServerTable.getInstance().getRegisteredGameServers().values())
 			_servers.add(new ServerData(client, gsi));
+		_charsOnServers = client.getCharsOnServ();
+		_charsToDelete = client.getCharsWaitingDelOnServ();
 	}
 	
 	@Override
@@ -129,5 +134,27 @@ public final class ServerList extends L2LoginServerPacket
 			writeD(server._serverType); // 1: Normal, 2: Relax, 4: Public Test, 8: No Label, 16: Character Creation Restricted, 32: Event, 64: Free
 			writeC(server._brackets ? 0x01 : 0x00);
 		}
+		writeH(0x00); // unknown
+		if (_charsOnServers != null)
+		{
+			writeC(_charsOnServers.size());
+			for (int servId : _charsOnServers.keySet())
+			{
+				writeC(servId);
+				writeC(_charsOnServers.get(servId));
+				if (_charsToDelete == null || !_charsToDelete.containsKey(servId))
+					writeC(0x00);
+				else
+				{
+					writeC(_charsToDelete.get(servId).length);
+					for (long deleteTime : _charsToDelete.get(servId))
+					{
+						writeD((int)((deleteTime-System.currentTimeMillis())/1000));
+					}
+				}
+			}
+		}
+		else
+			writeC(0x00);
 	}
 }