303 lines
8.2 KiB
Java
303 lines
8.2 KiB
Java
package org.moparscape.msc.gs.connection;
|
|
|
|
import java.net.InetAddress;
|
|
import java.net.InetSocketAddress;
|
|
import java.util.Map;
|
|
|
|
import org.apache.mina.common.IdleStatus;
|
|
import org.apache.mina.common.IoHandler;
|
|
import org.apache.mina.common.IoSession;
|
|
import org.apache.mina.filter.codec.ProtocolCodecFilter;
|
|
import org.moparscape.msc.config.Constants;
|
|
import org.moparscape.msc.gs.Instance;
|
|
import org.moparscape.msc.gs.core.GameEngine;
|
|
import org.moparscape.msc.gs.model.Player;
|
|
import org.moparscape.msc.gs.model.World;
|
|
import org.moparscape.msc.gs.util.Logger;
|
|
|
|
|
|
/**
|
|
* Handles the protocol events fired from MINA.
|
|
*/
|
|
public class RSCConnectionHandler implements IoHandler {
|
|
/**
|
|
* World instance
|
|
*/
|
|
|
|
// sudo
|
|
private static final World world = Instance.getWorld();
|
|
private long allowedInterval;
|
|
/*
|
|
|
|
private int attackers = 0;
|
|
|
|
private Map<InetAddress, Long> clients;
|
|
private Set<InetAddress> connectedAddresses;
|
|
private Map<InetAddress, Integer> counts;
|
|
private long lastAttack = 0;
|
|
*/
|
|
/**
|
|
* A reference to the game engine's packet queue
|
|
*/
|
|
|
|
private PacketQueue<RSCPacket> packets;
|
|
|
|
private Map<InetAddress, Integer> written;
|
|
|
|
/**
|
|
* Creates a new connection handler for the given engine.
|
|
*
|
|
* @param engine
|
|
* The engine in use
|
|
*/
|
|
public RSCConnectionHandler(GameEngine engine) {
|
|
packets = (PacketQueue<RSCPacket>) engine.getPacketQueue();
|
|
this.allowedInterval = allowedInterval;
|
|
/*
|
|
clients = Collections.synchronizedMap(new HashMap<InetAddress, Long>());
|
|
counts = Collections.synchronizedMap(new HashMap<InetAddress, Integer>());
|
|
written = Collections.synchronizedMap(new HashMap<InetAddress, Integer>());
|
|
connectedAddresses = new HashSet<InetAddress>();
|
|
*/
|
|
}
|
|
|
|
/*
|
|
public void connectionOk(IoSession io) {
|
|
counts.remove(getAddress(io));
|
|
}
|
|
|
|
public void delayClient(IoSession session, int delay) {
|
|
long d = System.currentTimeMillis() - delay;
|
|
clients.put(getAddress(session), d);
|
|
}
|
|
*/
|
|
/**
|
|
* Invoked whenever an exception is thrown by MINA or this IoHandler.
|
|
*
|
|
* @param session
|
|
* The associated session
|
|
* @param cause
|
|
* The exception thrown
|
|
*/
|
|
public void exceptionCaught(IoSession session, Throwable cause) {
|
|
Player p = (Player) session.getAttachment();
|
|
// if(p.getUsername().equalsIgnoreCase("xent")) {
|
|
|
|
// }
|
|
if(p != null)
|
|
p.getActionSender().sendLogout();
|
|
session.close();
|
|
/*
|
|
* Logging.debug("---MINA Error from: " + p.getUsername() +
|
|
* " -------"); cause.printStackTrace();Logging.debug(
|
|
* "------------------------------------------------------------");
|
|
*/
|
|
cause.printStackTrace();
|
|
}
|
|
|
|
private InetAddress getAddress(IoSession io) {
|
|
return ((InetSocketAddress) io.getRemoteAddress()).getAddress();
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Method responsible for deciding if a connection is OK to continue
|
|
*
|
|
* @param session
|
|
* The new session that will be verified
|
|
* @return True if the session meets the criteria, otherwise false (if
|
|
* false, adds to a IPSec filter & writes IP to log.
|
|
*/
|
|
/*
|
|
public boolean isConnectionOk(IoSession session) {
|
|
final InetAddress addr = getAddress(session);
|
|
final String ip = addr.toString().replaceAll("/", "");
|
|
// ip = ip.replaceAll("/","");
|
|
long now = System.currentTimeMillis();
|
|
int c = 0;
|
|
if (counts.containsKey(addr) && clients.containsKey(addr)) {
|
|
try {
|
|
c = counts.get(addr);
|
|
} catch (Exception e) {
|
|
Logging.debug("Error: " + e);
|
|
}
|
|
if (c >= 5) {
|
|
if (!written.containsKey(addr)) {
|
|
attackers++;
|
|
// if(now - lastAttack > 60000)
|
|
// {
|
|
// for(Player p : world.getPlayers())
|
|
// {
|
|
// p.save();
|
|
// p.getActionSender().sendLogout();
|
|
// }
|
|
// Instance.getServer().getLoginConnector().getActionSender().saveProfiles();
|
|
// }
|
|
try {
|
|
/*
|
|
* Logging.debug("ATTACKER IP: " + ip);
|
|
* BufferedWriter bf2 = new BufferedWriter(new
|
|
* FileWriter( "ddos.log", true));
|
|
* bf2.write("sudo /sbin/route add " +
|
|
* addr.getHostAddress() + " gw 127.0.0.1");
|
|
* bf2.newLine(); bf2.close();
|
|
* /
|
|
written.put(addr, 1);
|
|
Instance.getDelayedEventHandler().add(new DelayedEvent(null, 3600000) {
|
|
public void run() {
|
|
written.remove(addr);
|
|
counts.remove(addr);
|
|
try {
|
|
Runtime.getRuntime().exec("sudo /sbin/route delete " + ip);
|
|
} catch (Exception err) {
|
|
Logging.debug(err);
|
|
}
|
|
}
|
|
});
|
|
try {
|
|
Runtime.getRuntime().exec("sudo /sbin/route add " + ip + " gw 127.0.0.1");
|
|
} catch (Exception err) {
|
|
Logging.debug(err);
|
|
}
|
|
|
|
// try { Runtime.getRuntime().exec(ip + ".bat"); }
|
|
// catch (Exception err) { Logging.debug(err); }
|
|
lastAttack = now;
|
|
} catch (Exception e) {
|
|
System.err.println(e);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
if (clients.containsKey(addr)) {
|
|
long lastConnTime = clients.get(addr);
|
|
if (now - lastConnTime < 2000) {
|
|
if (!counts.containsKey(addr))
|
|
counts.put(addr, 0);
|
|
else
|
|
c = counts.get(addr) + 1;
|
|
counts.put(addr, c);
|
|
return false;
|
|
} else {
|
|
clients.put(addr, now);
|
|
if (counts.containsKey(addr))
|
|
counts.remove(addr);
|
|
return true;
|
|
}
|
|
} else {
|
|
clients.put(addr, now);
|
|
return true;
|
|
}
|
|
}
|
|
*/
|
|
/**
|
|
* Invoked whenever a packet is ready to be added to the queue.
|
|
*
|
|
* @param session
|
|
* The IO session on which the packet was received
|
|
* @param message
|
|
* The packet
|
|
*/
|
|
public void messageReceived(IoSession session, Object message) {
|
|
Player player = (Player) session.getAttachment();
|
|
if (session.isClosing() || player.destroyed()) {
|
|
return;
|
|
}
|
|
RSCPacket p = (RSCPacket) message;
|
|
|
|
/* if(p.getID() == 57 || p.getID() == 73 || p.getID() == 40 || p.getID()
|
|
== 51 || p.getID() == 128 || p.getID() == 206 || p.getID() == 71 ||
|
|
p.getID() == 55)*/
|
|
|
|
if(p.getID() == 55)
|
|
player.addInterval();
|
|
|
|
|
|
player.addPacket(p);
|
|
packets.add(p);
|
|
}
|
|
|
|
/**
|
|
* Invoked whenever a packet is sent.
|
|
*
|
|
* @param session
|
|
* The associated session
|
|
* @param message
|
|
* The packet sent
|
|
*/
|
|
public void messageSent(IoSession session, Object message) {
|
|
}
|
|
|
|
/**
|
|
* Invoked whenever an IO session is closed. This must handle unregistering
|
|
* the disconnecting player from the engine.
|
|
*
|
|
* @param session
|
|
* The IO session which has been closed
|
|
*/
|
|
public void sessionClosed(IoSession session) {
|
|
Player player = (Player) session.getAttachment();
|
|
if (!player.destroyed()) {
|
|
player.destroy(false);
|
|
}
|
|
}
|
|
|
|
public void sessionCreated(IoSession session) {
|
|
/*
|
|
if (!isConnectionOk(session)) {
|
|
session.close();
|
|
return;
|
|
} else {
|
|
connectionOk(session);
|
|
}
|
|
*/
|
|
session.getFilterChain().addFirst("protocolFilter", new ProtocolCodecFilter(new RSCCodecFactory()));
|
|
// Logger.event("Connection from: " +
|
|
// ((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress());
|
|
Logger.println("Connection from: " + ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress());
|
|
}
|
|
|
|
/**
|
|
* Invoked when the idle status of a session changes.
|
|
*
|
|
* @param session
|
|
* The session in question
|
|
* @param status
|
|
* The new idle status
|
|
*/
|
|
public void sessionIdle(IoSession session, IdleStatus status) {
|
|
Player player = (Player) session.getAttachment();
|
|
if (!player.destroyed()) {
|
|
player.destroy(false);
|
|
}
|
|
session.close();
|
|
}
|
|
|
|
/**
|
|
* Invoked when a new session is opened.
|
|
*
|
|
* @param session
|
|
* The session opened
|
|
*/
|
|
public void sessionOpened(IoSession session) {
|
|
Constants.GameServer.ACCEPTED_CONNECTIONS++;
|
|
session.setAttachment(new Player(session));
|
|
session.setIdleTime(IdleStatus.BOTH_IDLE, 30);
|
|
session.setWriteTimeout(30);
|
|
}
|
|
|
|
/**
|
|
* Sets the interval between connections from a client. This value is
|
|
* measured in milliseconds.
|
|
*
|
|
* @param allowedInterval
|
|
* The number of milliseconds a client is allowed to wait before
|
|
* making another successful connection
|
|
*/
|
|
public void setAllowedInterval(long allowedInterval) {
|
|
this.allowedInterval = allowedInterval;
|
|
}
|
|
}
|