serverList = GameServerTable.getInstance().getRegisteredGameServers().values();
for (GameServerInfo gsi : serverList)
{
if (gsi.isAuthed())
{
gsi.getGameServerThread().requestCharacters(account);
}
}
}
/**
* @param client
* @param serverId
* @return
*/
public boolean isLoginPossible(L2LoginClient client, int serverId)
{
GameServerInfo gsi = GameServerTable.getInstance().getRegisteredGameServerById(serverId);
int access = client.getAccessLevel();
if ((gsi != null) && gsi.isAuthed())
{
boolean loginOk = ((gsi.getCurrentPlayerCount() < gsi.getMaxPlayers()) && (gsi.getStatus() != ServerStatus.STATUS_GM_ONLY)) || (access > 0);
if (loginOk && (client.getLastServer() != serverId))
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(ACCOUNT_LAST_SERVER_UPDATE))
{
ps.setInt(1, serverId);
ps.setString(2, client.getAccount());
ps.executeUpdate();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not set lastServer: " + e.getMessage(), e);
}
}
return loginOk;
}
return false;
}
public void setAccountAccessLevel(String account, int banLevel)
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(ACCOUNT_ACCESS_LEVEL_UPDATE))
{
ps.setInt(1, banLevel);
ps.setString(2, account);
ps.executeUpdate();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not set accessLevel: " + e.getMessage(), e);
}
}
public void setAccountLastTracert(String account, String pcIp, String hop1, String hop2, String hop3, String hop4)
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(ACCOUNT_IPS_UPDATE))
{
ps.setString(1, pcIp);
ps.setString(2, hop1);
ps.setString(3, hop2);
ps.setString(4, hop3);
ps.setString(5, hop4);
ps.setString(6, account);
ps.executeUpdate();
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not set last tracert: " + e.getMessage(), e);
}
}
public void setCharactersOnServer(String account, int charsNum, long[] timeToDel, int serverId)
{
L2LoginClient client = _loginServerClients.get(account);
if (client == null)
{
return;
}
if (charsNum > 0)
{
client.setCharsOnServ(serverId, charsNum);
}
if (timeToDel.length > 0)
{
client.serCharsWaitingDelOnServ(serverId, timeToDel);
}
}
/**
*
* This method returns one of the cached {@link ScrambledKeyPair ScrambledKeyPairs} for communication with Login Clients.
*
* @return a scrambled keypair
*/
public ScrambledKeyPair getScrambledRSAKeyPair()
{
return _keyPairs[Rnd.nextInt(10)];
}
/**
* @param client the client
* @param address client host address
* @param info the account info to checkin
* @return true when ok to checkin, false otherwise
*/
public boolean canCheckin(L2LoginClient client, InetAddress address, AccountInfo info)
{
try
{
List ipWhiteList = new ArrayList<>();
List ipBlackList = new ArrayList<>();
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(ACCOUNT_IPAUTH_SELECT))
{
ps.setString(1, info.getLogin());
try (ResultSet rset = ps.executeQuery())
{
String ip, type;
while (rset.next())
{
ip = rset.getString("ip");
type = rset.getString("type");
if (!isValidIPAddress(ip))
{
continue;
}
else if (type.equals("allow"))
{
ipWhiteList.add(InetAddress.getByName(ip));
}
else if (type.equals("deny"))
{
ipBlackList.add(InetAddress.getByName(ip));
}
}
}
}
// Check IP
if (!ipWhiteList.isEmpty() || !ipBlackList.isEmpty())
{
if (!ipWhiteList.isEmpty() && !ipWhiteList.contains(address))
{
_log.warning("Account checkin attemp from address(" + address.getHostAddress() + ") not present on whitelist for account '" + info.getLogin() + "'.");
return false;
}
if (!ipBlackList.isEmpty() && ipBlackList.contains(address))
{
_log.warning("Account checkin attemp from address(" + address.getHostAddress() + ") on blacklist for account '" + info.getLogin() + "'.");
return false;
}
}
client.setAccessLevel(info.getAccessLevel());
client.setLastServer(info.getLastServer());
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(ACCOUNT_INFO_UPDATE))
{
ps.setLong(1, System.currentTimeMillis());
ps.setString(2, address.getHostAddress());
ps.setString(3, info.getLogin());
ps.execute();
}
return true;
}
catch (Exception e)
{
_log.log(Level.WARNING, "Could not finish login process!", e);
return false;
}
}
public boolean isValidIPAddress(String ipAddress)
{
String[] parts = ipAddress.split("\\.");
if (parts.length != 4)
{
return false;
}
for (String s : parts)
{
int i = Integer.parseInt(s);
if ((i < 0) || (i > 255))
{
return false;
}
}
return true;
}
public static void load() throws GeneralSecurityException
{
synchronized (LoginController.class)
{
if (_instance == null)
{
_instance = new LoginController();
}
else
{
throw new IllegalStateException("LoginController can only be loaded a single time.");
}
}
}
public static LoginController getInstance()
{
return _instance;
}
class PurgeThread extends Thread
{
public PurgeThread()
{
setName("PurgeThread");
}
@Override
public void run()
{
while (!isInterrupted())
{
for (L2LoginClient client : _loginServerClients.values())
{
if (client == null)
{
continue;
}
if ((client.getConnectionStartTime() + LOGIN_TIMEOUT) < System.currentTimeMillis())
{
client.close(LoginFailReason.REASON_ACCESS_FAILED);
}
}
try
{
Thread.sleep(LOGIN_TIMEOUT / 2);
}
catch (InterruptedException e)
{
return;
}
}
}
}
public static enum AuthLoginResult
{
INVALID_PASSWORD,
ACCOUNT_BANNED,
ALREADY_ON_LS,
ALREADY_ON_GS,
AUTH_SUCCESS
}
}