MoparClassic/GameServer/src/org/moparscape/msc/gs/connection/RSCConnectionHandler.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;
}
}