package javastory.login;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javastory.server.TimerManager;
import javastory.tools.LogUtil;
import com.google.common.collect.Lists;
public class LoginWorker {
private static class AccountIpEntry {
private final int AccountId;
private final String IpAddress;
public AccountIpEntry(final int id, final String entry) {
this.AccountId = id;
this.IpAddress = entry;
}
public int getAccountId() {
return this.AccountId;
}
public String getIpAddress() {
return this.IpAddress;
}
}
private static Runnable persister;
private static final List<AccountIpEntry> ACCOUNT_IP_LOG = Lists.newLinkedList();
private static long lastUpdate = 0;
private static final Lock mutex = new ReentrantLock();
protected LoginWorker() {
persister = new PersistingTask();
TimerManager.getInstance().register(persister, 1800000); // 30 min once
}
private static class PersistingTask implements Runnable {
@Override
public void run() {
final StringBuilder sb = new StringBuilder();
mutex.lock();
try {
final String time = LogUtil.CurrentReadable_Time();
for (final AccountIpEntry logentry : ACCOUNT_IP_LOG) {
sb.append("AccountId : ");
sb.append(logentry.getAccountId());
sb.append(", IP : ");
sb.append(logentry.getIpAddress());
sb.append(", TIME : ");
sb.append(time);
sb.append("\n");
}
ACCOUNT_IP_LOG.clear();
} finally {
mutex.unlock();
}
LogUtil.log(LogUtil.IP_Log, sb.toString());
}
}
public static void registerClient(final LoginClient c) {
c.write(LoginPacket.getAuthSuccessRequest(c));
c.setIdleTask(TimerManager.getInstance().schedule(new Runnable() {
@Override
public void run() {
c.disconnect();
}
}, 10 * 60 * 10000));
final LoginServer loginServer = LoginServer.getInstance();
if (System.currentTimeMillis() - lastUpdate > 300000) {
// Update once every 5 minutes
lastUpdate = System.currentTimeMillis();
try {
final Map<Integer, Integer> channelLoad = loginServer.getWorldInterface().getChannelLoad();
if (channelLoad == null) {
// In an unfortunate event that client logged in before load
lastUpdate = 0;
c.write(LoginPacket.getLoginFailed(AuthReplyCode.TOO_MANY_CONNECTIONS));
return;
}
for (final Entry<Integer, Integer> entry : channelLoad.entrySet()) {
final int load = Math.min(1200, entry.getValue());
loginServer.setLoad(entry.getKey(), load);
}
} catch (final RemoteException ex) {
LoginServer.getInstance().pingWorld();
}
}
c.write(LoginPacket.getWorldList(2, "Cassiopeia", loginServer.getChannels()));
c.write(LoginPacket.getEndOfWorldList());
mutex.lock();
try {
ACCOUNT_IP_LOG.add(new AccountIpEntry(c.getAccountId(), c.getSessionIP()));
} finally {
mutex.unlock();
}
}
}