Major schedules & DB refactor
Refactored many calls for TimerManager's schedules throughout the source. Switched all tables using MyISAM to InnoDB: on a multi-threaded environment such as this, table-locking is an instant no-no, and other gains MyISAM would have over InnoDB are minimal. Altered getConnection() to properly throw an exception (good practice!) in case of no available connection instead of a mere null.
This commit is contained in:
@@ -37,6 +37,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@@ -63,6 +64,7 @@ import server.TimerManager;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.FilePrinter;
|
||||
import tools.Pair;
|
||||
import client.MapleClient;
|
||||
import client.MapleCharacter;
|
||||
import client.SkillFactory;
|
||||
import constants.ItemConstants;
|
||||
@@ -82,7 +84,8 @@ public class Server implements Runnable {
|
||||
private static Server instance = null;
|
||||
private List<Pair<Integer, String>> worldRecommendedList = new LinkedList<>();
|
||||
private final Map<Integer, MapleGuild> guilds = new LinkedHashMap<>();
|
||||
private final Lock shutdownLock = new ReentrantLock();
|
||||
private final Map<MapleClient, Long> inLoginState = new LinkedHashMap<>();
|
||||
private final Lock srvLock = new ReentrantLock();
|
||||
private final PlayerBuffStorage buffStorage = new PlayerBuffStorage();
|
||||
private final Map<Integer, MapleAlliance> alliances = new LinkedHashMap<>();
|
||||
private boolean online = false;
|
||||
@@ -279,6 +282,7 @@ public class Server implements Runnable {
|
||||
TimerManager tMan = TimerManager.getInstance();
|
||||
tMan.start();
|
||||
tMan.register(tMan.purge(), ServerConstants.PURGING_INTERVAL);//Purging ftw...
|
||||
disconnectIdlesOnLoginTask();
|
||||
|
||||
long timeLeft = getTimeLeftForNextHour();
|
||||
tMan.register(new CouponWorker(), ServerConstants.COUPON_INTERVAL, timeLeft);
|
||||
@@ -720,11 +724,64 @@ public class Server implements Runnable {
|
||||
return worlds;
|
||||
}
|
||||
|
||||
public void registerLoginState(MapleClient c) {
|
||||
srvLock.lock();
|
||||
try {
|
||||
inLoginState.put(c, System.currentTimeMillis() + 600000);
|
||||
} finally {
|
||||
srvLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterLoginState(MapleClient c) {
|
||||
srvLock.lock();
|
||||
try {
|
||||
inLoginState.remove(c);
|
||||
} finally {
|
||||
srvLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void disconnectIdlesOnLoginState() {
|
||||
srvLock.lock();
|
||||
try {
|
||||
List<MapleClient> toDisconnect = new LinkedList<>();
|
||||
long timeNow = System.currentTimeMillis();
|
||||
|
||||
for(Entry<MapleClient, Long> mc : inLoginState.entrySet()) {
|
||||
if(timeNow > mc.getValue()) {
|
||||
toDisconnect.add(mc.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
for(MapleClient c : toDisconnect) {
|
||||
if(c.isLoggedIn()) {
|
||||
c.disconnect(false, false);
|
||||
} else {
|
||||
c.getSession().close(true);
|
||||
}
|
||||
|
||||
inLoginState.remove(c);
|
||||
}
|
||||
} finally {
|
||||
srvLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void disconnectIdlesOnLoginTask() {
|
||||
TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
disconnectIdlesOnLoginState();
|
||||
}
|
||||
}, 300000);
|
||||
}
|
||||
|
||||
public final Runnable shutdown(final boolean restart) {//no player should be online when trying to shutdown!
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
shutdownLock.lock();
|
||||
srvLock.lock();
|
||||
|
||||
try {
|
||||
System.out.println((restart ? "Restarting" : "Shutting down") + " the server!\r\n");
|
||||
@@ -788,7 +845,7 @@ public class Server implements Runnable {
|
||||
getInstance().run();//DID I DO EVERYTHING?! D:
|
||||
}
|
||||
} finally {
|
||||
shutdownLock.unlock();
|
||||
srvLock.unlock();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -297,7 +297,7 @@ public final class BBSOperationHandler extends AbstractMaplePacketHandler {
|
||||
if (mc.getGuildId() <= 0) {
|
||||
return;
|
||||
}
|
||||
Connection con = null;
|
||||
Connection con;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps2;
|
||||
|
||||
@@ -65,6 +65,7 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
|
||||
mc.cancelDiseaseExpireTask();
|
||||
mc.cancelSkillCooldownTask();
|
||||
mc.cancelExpirationTask();
|
||||
mc.cancelQuestExpirationTask();
|
||||
|
||||
c.announce(MaplePacketCreator.openCashShop(c, false));
|
||||
c.announce(MaplePacketCreator.showCashInventory(c));
|
||||
|
||||
@@ -74,6 +74,7 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
chr.cancelDiseaseExpireTask();
|
||||
chr.cancelSkillCooldownTask();
|
||||
chr.cancelExpirationTask();
|
||||
chr.cancelQuestExpirationTask();
|
||||
|
||||
chr.saveToDB();
|
||||
chr.getMap().removePlayer(c.getPlayer());
|
||||
|
||||
@@ -343,15 +343,15 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
} else if (op == 9) { //add to cart
|
||||
int id = slea.readInt(); //id of the item
|
||||
Connection con = null;
|
||||
Connection con;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
try (PreparedStatement ps1 = con.prepareStatement("SELECT * FROM mts_items WHERE id = ? AND seller <> ?")) {
|
||||
ps1.setInt(1, id);//Previene que agregues al cart tus propios items
|
||||
try (PreparedStatement ps1 = con.prepareStatement("SELECT id FROM mts_items WHERE id = ? AND seller <> ?")) {
|
||||
ps1.setInt(1, id); //Dummy query, prevents adding to cart self owned items
|
||||
ps1.setInt(2, c.getPlayer().getId());
|
||||
try (ResultSet rs1 = ps1.executeQuery()) {
|
||||
if (rs1.next()) {
|
||||
PreparedStatement ps = con.prepareStatement("SELECT * FROM mts_cart WHERE cid = ? AND itemid = ?");
|
||||
PreparedStatement ps = con.prepareStatement("SELECT cid FROM mts_cart WHERE cid = ? AND itemid = ?");
|
||||
ps.setInt(1, c.getPlayer().getId());
|
||||
ps.setInt(2, id);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
|
||||
@@ -267,6 +267,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
player.diseaseExpireTask();
|
||||
player.skillCooldownTask();
|
||||
player.expirationTask();
|
||||
player.questExpirationTask();
|
||||
if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) {
|
||||
player.createDragon();
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ public class MapleAlliance {
|
||||
ps.close();
|
||||
rs.close();
|
||||
|
||||
ps = con.prepareStatement("SELECT * FROM allianceguilds WHERE allianceid = ?");
|
||||
ps = con.prepareStatement("SELECT guildid FROM allianceguilds WHERE allianceid = ?");
|
||||
ps.setInt(1, id);
|
||||
rs = ps.executeQuery();
|
||||
|
||||
|
||||
@@ -26,10 +26,12 @@ import net.MaplePacketHandler;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public class KeepAliveHandler implements MaplePacketHandler {
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
c.pongReceived();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateState(MapleClient c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,9 +41,7 @@ public final class CharSelectedHandler extends AbstractMaplePacketHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (c.getIdleTask() != null) {
|
||||
c.getIdleTask().cancel(true);
|
||||
}
|
||||
Server.getInstance().unregisterLoginState(c);
|
||||
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
|
||||
String[] socket = Server.getInstance().getIP(c.getWorld(), c.getChannel()).split(":");
|
||||
try {
|
||||
|
||||
@@ -26,9 +26,7 @@ public class CharSelectedWithPicHandler extends AbstractMaplePacketHandler {
|
||||
return;
|
||||
}
|
||||
if (c.checkPic(pic)) {
|
||||
if (c.getIdleTask() != null) {
|
||||
c.getIdleTask().cancel(true);
|
||||
}
|
||||
Server.getInstance().unregisterLoginState(c);
|
||||
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
|
||||
|
||||
String[] socket = Server.getInstance().getIP(c.getWorld(), c.getChannel()).split(":");
|
||||
|
||||
@@ -24,6 +24,7 @@ package net.server.handlers.login;
|
||||
import java.util.Calendar;
|
||||
|
||||
import net.MaplePacketHandler;
|
||||
import net.server.Server;
|
||||
import server.TimerManager;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -73,12 +74,7 @@ public final class LoginPasswordHandler implements MaplePacketHandler {
|
||||
|
||||
private static void login(MapleClient c){
|
||||
c.announce(MaplePacketCreator.getAuthSuccess(c));//why the fk did I do c.getAccountName()?
|
||||
final MapleClient client = c;
|
||||
c.setIdleTask(TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.disconnect(false, false);
|
||||
}
|
||||
}, 600000));
|
||||
|
||||
Server.getInstance().registerLoginState(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,9 +49,7 @@ public final class PickCharHandler extends AbstractMaplePacketHandler {
|
||||
e.printStackTrace();
|
||||
c.setChannel(1);
|
||||
}
|
||||
if (c.getIdleTask() != null) {
|
||||
c.getIdleTask().cancel(true);
|
||||
}
|
||||
Server.getInstance().unregisterLoginState(c);
|
||||
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
|
||||
String[] socket = Server.getInstance().getIP(c.getWorld(), c.getChannel()).split(":");
|
||||
try {
|
||||
|
||||
@@ -29,9 +29,7 @@ public final class RegisterPicHandler extends AbstractMaplePacketHandler {
|
||||
String pic = slea.readMapleAsciiString();
|
||||
if (c.getPic() == null || c.getPic().equals("")) {
|
||||
c.setPic(pic);
|
||||
if (c.getIdleTask() != null) {
|
||||
c.getIdleTask().cancel(true);
|
||||
}
|
||||
Server.getInstance().unregisterLoginState(c);
|
||||
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
|
||||
String[] socket = Server.getInstance().getIP(c.getWorld(), c.getChannel()).split(":");
|
||||
try {
|
||||
|
||||
@@ -24,7 +24,7 @@ package net.server.handlers.login;
|
||||
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import server.TimerManager;
|
||||
import net.server.Server;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
@@ -40,12 +40,8 @@ public class SetGenderHandler extends AbstractMaplePacketHandler {
|
||||
c.setGender(slea.readByte());
|
||||
c.announce(MaplePacketCreator.getAuthSuccess(c));
|
||||
final MapleClient client = c;
|
||||
c.setIdleTask(TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.getSession().close(true);
|
||||
}
|
||||
}, 600000));
|
||||
|
||||
Server.getInstance().registerLoginState(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,7 @@ public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandle
|
||||
return;
|
||||
}
|
||||
if (c.checkPic(pic)) {
|
||||
if (c.getIdleTask() != null) {
|
||||
c.getIdleTask().cancel(true);
|
||||
}
|
||||
Server.getInstance().unregisterLoginState(c);
|
||||
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
|
||||
|
||||
String[] socket = Server.getInstance().getIP(c.getWorld(), c.getChannel()).split(":");
|
||||
|
||||
@@ -28,9 +28,7 @@ public final class ViewAllPicRegisterHandler extends AbstractMaplePacketHandler
|
||||
slea.readMapleAsciiString();
|
||||
String pic = slea.readMapleAsciiString();
|
||||
c.setPic(pic);
|
||||
if (c.getIdleTask() != null) {
|
||||
c.getIdleTask().cancel(true);
|
||||
}
|
||||
Server.getInstance().unregisterLoginState(c);
|
||||
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
|
||||
String[] socket = Server.getInstance().getIP(c.getWorld(), channel).split(":");
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user