BukkitTelnet/src/main/java/me/totalfreedom/bukkittelnet/SocketListener.java

149 lines
3.9 KiB
Java

package me.totalfreedom.bukkittelnet;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import me.totalfreedom.bukkittelnet.session.ClientSession;
public class SocketListener extends Thread
{
public static long LISTEN_THRESHOLD_MILLIS = 10000;
//
private final TelnetServer telnet;
private final ServerSocket serverSocket;
private final List<ClientSession> clientSessions = new ArrayList<>();
private final Map<InetAddress, Long> recentIPs = new HashMap<>();
public SocketListener(TelnetServer telnet, ServerSocket serverSocket)
{
this.telnet = telnet;
this.serverSocket = serverSocket;
}
@Override
public void run()
{
while (!serverSocket.isClosed())
{
final Socket clientSocket;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException ex)
{
continue;
}
// Remove old entries
recentIPs.entrySet().removeIf(inetAddressLongEntry -> inetAddressLongEntry.getValue() + LISTEN_THRESHOLD_MILLIS < System.currentTimeMillis());
final InetAddress addr = clientSocket.getInetAddress();
if (addr == null)
{
return; // Socket is not connected
}
// Connect Threshold
if (recentIPs.containsKey(addr))
{
recentIPs.put(addr, System.currentTimeMillis());
try
{
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
writer.write("Connection throttled. Please wait a minute and try again.\r\n");
writer.flush();
}
catch (IOException ignored)
{
}
try
{
clientSocket.close();
}
catch (IOException ignored)
{
}
continue;
}
recentIPs.put(addr, System.currentTimeMillis());
final ClientSession clientSession = new ClientSession(telnet, clientSocket);
clientSessions.add(clientSession);
clientSession.start();
removeDisconnected();
}
TelnetLogger.info("Server closed");
}
private void removeDisconnected()
{
final Iterator<ClientSession> it = clientSessions.iterator();
while (it.hasNext())
{
final ClientSession session = it.next();
if (!session.syncIsConnected())
{
telnet.getPlugin().appender.removeSession(session);
it.remove();
}
}
}
public void triggerPlayerListUpdates(final String playerListData)
{
clientSessions.forEach(session ->
session.syncTriggerPlayerListUpdate(playerListData));
}
public void triggerDataUsageUpdates(final String usageData)
{
clientSessions.forEach(session ->
session.syncUsageUpdate(usageData));
}
public void stopServer()
{
try
{
serverSocket.close();
}
catch (IOException ex)
{
TelnetLogger.severe(ex);
}
for (ClientSession session : clientSessions)
{
session.syncTerminateSession();
}
clientSessions.clear();
}
public List<ClientSession> getSessions()
{
return Collections.unmodifiableList(clientSessions);
}
}