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:
@@ -257,6 +257,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private Map<Integer, MapleCoolDownValueHolder> coolDowns = new LinkedHashMap<>();
|
||||
private EnumMap<MapleDisease, MapleDiseaseValueHolder> diseases = new EnumMap<>(MapleDisease.class);
|
||||
private Map<Integer, MapleDoor> doors = new LinkedHashMap<>();
|
||||
private Map<MapleQuest, Long> questExpirations = new LinkedHashMap<>();
|
||||
private ScheduledFuture<?> dragonBloodSchedule;
|
||||
private ScheduledFuture<?> hpDecreaseTask;
|
||||
private ScheduledFuture<?> beholderHealingSchedule, beholderBuffSchedule, berserkSchedule;
|
||||
@@ -264,14 +265,14 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private ScheduledFuture<?> buffExpireTask = null;
|
||||
private ScheduledFuture<?> itemExpireTask = null;
|
||||
private ScheduledFuture<?> diseaseExpireTask = null;
|
||||
private ScheduledFuture<?> questExpireTask = null;
|
||||
private ScheduledFuture<?> recoveryTask = null;
|
||||
private ScheduledFuture<?> extraRecoveryTask = null;
|
||||
private ScheduledFuture<?> chairRecoveryTask = null;
|
||||
private ScheduledFuture<?> pendantOfSpirit = null; //1122017
|
||||
private List<ScheduledFuture<?>> timers = new ArrayList<>();
|
||||
private Lock chrLock = new ReentrantLock(true);
|
||||
private Lock effLock = new ReentrantLock(true);
|
||||
private Lock petLock = new ReentrantLock(true);
|
||||
private Lock petLock = new ReentrantLock(true); // for quest tasks as well
|
||||
private Lock prtLock = new ReentrantLock();
|
||||
private Map<Integer, Set<Integer>> excluded = new LinkedHashMap<>();
|
||||
private Set<Integer> excludedItems = new LinkedHashSet<>();
|
||||
@@ -2088,13 +2089,15 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
addHP(-getMap().getHPDec());
|
||||
lastHpDec = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
|
||||
}
|
||||
|
||||
private void startHpDecreaseTask(long lastHpTask) {
|
||||
hpDecreaseTask = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doHurtHp();
|
||||
}
|
||||
}, 10000);
|
||||
}, 10000, 10000 - lastHpTask);
|
||||
}
|
||||
|
||||
public void resetHpDecreaseTask() {
|
||||
@@ -2103,16 +2106,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
long lastHpTask = System.currentTimeMillis() - lastHpDec;
|
||||
if(lastHpTask >= 10000) {
|
||||
doHurtHp();
|
||||
} else {
|
||||
hpDecreaseTask = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doHurtHp();
|
||||
}
|
||||
}, 10000 - lastHpTask);
|
||||
}
|
||||
startHpDecreaseTask((lastHpTask > 10000) ? 10000 : lastHpTask);
|
||||
}
|
||||
|
||||
public void dropMessage(String message) {
|
||||
@@ -2127,10 +2121,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return nf.format(MapleGuild.CHANGE_EMBLEM_COST);
|
||||
}
|
||||
|
||||
public List<ScheduledFuture<?>> getTimers() {
|
||||
return timers;
|
||||
}
|
||||
|
||||
private void enforceMaxHpMp() {
|
||||
List<Pair<MapleStat, Integer>> stats = new ArrayList<>(2);
|
||||
if (getMp() > getCurrentMaxMp()) {
|
||||
@@ -7221,7 +7211,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
public void showNote() {
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM notes WHERE `to`=? AND `deleted` = 0", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM notes WHERE `to` = ? AND `deleted` = 0", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
|
||||
ps.setString(1, this.getName());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
rs.last();
|
||||
@@ -7466,15 +7456,83 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
updateQuest(newStatus);
|
||||
}
|
||||
|
||||
public void questTimeLimit(final MapleQuest quest, int seconds) {
|
||||
ScheduledFuture<?> sf = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
expireQuest(quest);
|
||||
public void cancelQuestExpirationTask() {
|
||||
petLock.lock();
|
||||
try {
|
||||
if (questExpireTask != null) {
|
||||
questExpireTask.cancel(false);
|
||||
questExpireTask = null;
|
||||
}
|
||||
}, seconds * 1000);
|
||||
} finally {
|
||||
petLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void questExpirationTask() {
|
||||
petLock.lock();
|
||||
try {
|
||||
if(!questExpirations.isEmpty()) {
|
||||
if(questExpireTask == null) {
|
||||
questExpireTask = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runQuestExpireTask();
|
||||
}
|
||||
}, 10 * 1000);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
petLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void runQuestExpireTask() {
|
||||
petLock.lock();
|
||||
try {
|
||||
long timeNow = System.currentTimeMillis();
|
||||
List<MapleQuest> expireList = new LinkedList<>();
|
||||
|
||||
for(Entry<MapleQuest, Long> qe : questExpirations.entrySet()) {
|
||||
if(qe.getValue() <= timeNow) expireList.add(qe.getKey());
|
||||
}
|
||||
|
||||
if(!expireList.isEmpty()) {
|
||||
for(MapleQuest quest : expireList) {
|
||||
expireQuest(quest);
|
||||
questExpirations.remove(quest);
|
||||
}
|
||||
|
||||
if(questExpirations.isEmpty()) {
|
||||
questExpireTask.cancel(false);
|
||||
questExpireTask = null;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
petLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void registerQuestExpire(MapleQuest quest, long time) {
|
||||
petLock.lock();
|
||||
try {
|
||||
if(questExpireTask == null) {
|
||||
questExpireTask = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runQuestExpireTask();
|
||||
}
|
||||
}, 10 * 1000);
|
||||
}
|
||||
|
||||
questExpirations.put(quest, System.currentTimeMillis() + time);
|
||||
} finally {
|
||||
petLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void questTimeLimit(final MapleQuest quest, int seconds) {
|
||||
registerQuestExpire(quest, seconds * 1000);
|
||||
announce(MaplePacketCreator.addQuestTimeLimit(quest.getId(), seconds * 1000));
|
||||
timers.add(sf);
|
||||
}
|
||||
|
||||
public void questTimeLimit2(final MapleQuest quest, long expires) {
|
||||
@@ -7483,14 +7541,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
if(timeLeft <= 0) {
|
||||
expireQuest(quest);
|
||||
} else {
|
||||
ScheduledFuture<?> sf = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
expireQuest(quest);
|
||||
}
|
||||
}, timeLeft);
|
||||
|
||||
timers.add(sf);
|
||||
registerQuestExpire(quest, timeLeft);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7903,10 +7954,19 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
cancelSkillCooldownTask();
|
||||
cancelExpirationTask();
|
||||
|
||||
for (ScheduledFuture<?> sf : timers) {
|
||||
sf.cancel(false);
|
||||
petLock.lock();
|
||||
try {
|
||||
if (questExpireTask != null) {
|
||||
questExpireTask.cancel(false);
|
||||
questExpireTask = null;
|
||||
|
||||
questExpirations.clear();
|
||||
questExpirations = null;
|
||||
}
|
||||
} finally {
|
||||
petLock.unlock();
|
||||
}
|
||||
timers.clear();
|
||||
|
||||
if (maplemount != null) {
|
||||
maplemount.empty();
|
||||
maplemount = null;
|
||||
@@ -7921,7 +7981,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
family = null;
|
||||
client = null;
|
||||
map = null;
|
||||
timers = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@@ -70,7 +69,6 @@ import scripting.quest.QuestActionManager;
|
||||
import scripting.quest.QuestScriptManager;
|
||||
import server.life.MapleMonster;
|
||||
import server.MapleTrade;
|
||||
import server.TimerManager;
|
||||
import server.maps.*;
|
||||
import server.quest.MapleQuest;
|
||||
import tools.LogHelper;
|
||||
@@ -101,7 +99,6 @@ public class MapleClient {
|
||||
private int gmlevel;
|
||||
private Set<String> macs = new HashSet<>();
|
||||
private Map<String, ScriptEngine> engines = new HashMap<>();
|
||||
private ScheduledFuture<?> idleTask = null;
|
||||
private byte characterSlots = 3;
|
||||
private byte loginattempt = 0;
|
||||
private String pin = null;
|
||||
@@ -941,15 +938,13 @@ public class MapleClient {
|
||||
}
|
||||
|
||||
private void clear() { //usable when defining client = null shortly after
|
||||
Server.getInstance().unregisterLoginState(this);
|
||||
|
||||
this.accountName = null;
|
||||
this.macs = null;
|
||||
this.hwid = null;
|
||||
this.birthday = null;
|
||||
//this.engines = null;
|
||||
if (this.idleTask != null) {
|
||||
this.idleTask.cancel(true);
|
||||
this.idleTask = null;
|
||||
}
|
||||
this.player = null;
|
||||
this.receive = null;
|
||||
this.send = null;
|
||||
@@ -1005,25 +1000,17 @@ public class MapleClient {
|
||||
lastPong = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void sendPing() {
|
||||
final long then = System.currentTimeMillis();
|
||||
announce(MaplePacketCreator.getPing());
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (lastPong < then) {
|
||||
if (session != null && session.isConnected()) {
|
||||
session.close(false);
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, 15000);
|
||||
}
|
||||
public void testPing(long timeThen) {
|
||||
try {
|
||||
if (lastPong < timeThen) {
|
||||
if (session != null && session.isConnected()) {
|
||||
session.close(false);
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String getHWID() {
|
||||
return hwid;
|
||||
@@ -1053,14 +1040,6 @@ public class MapleClient {
|
||||
engines.remove(name);
|
||||
}
|
||||
|
||||
public ScheduledFuture<?> getIdleTask() {
|
||||
return idleTask;
|
||||
}
|
||||
|
||||
public void setIdleTask(ScheduledFuture<?> idleTask) {
|
||||
this.idleTask = idleTask;
|
||||
}
|
||||
|
||||
public NPCConversationManager getCM() {
|
||||
return NPCScriptManager.getInstance().getCM(this);
|
||||
}
|
||||
@@ -1321,6 +1300,7 @@ public class MapleClient {
|
||||
player.cancelBuffExpireTask();
|
||||
player.cancelDiseaseExpireTask();
|
||||
player.cancelSkillCooldownTask();
|
||||
player.cancelQuestExpirationTask();
|
||||
//Cancelling magicdoor? Nope
|
||||
//Cancelling mounts? Noty
|
||||
if (player.getBuffedValue(MapleBuffStat.PUPPET) != null) {
|
||||
|
||||
@@ -349,6 +349,10 @@ public class Commands {
|
||||
break;
|
||||
|
||||
case "staff":
|
||||
player.yellowMessage("MapleSolaxiaV2 Staff");
|
||||
player.yellowMessage("Ronan - Developer");
|
||||
player.yellowMessage("Vcoc - Freelance Developer");
|
||||
player.yellowMessage("");
|
||||
player.yellowMessage("MapleSolaxia Staff");
|
||||
player.yellowMessage("Aria - Administrator");
|
||||
player.yellowMessage("Twdtwd - Administrator");
|
||||
@@ -358,9 +362,6 @@ public class Commands {
|
||||
player.yellowMessage("SourMjolk - Game Master");
|
||||
player.yellowMessage("Kanade - Game Master");
|
||||
player.yellowMessage("Kitsune - Game Master");
|
||||
player.yellowMessage("MapleSolaxiaV2 Staff");
|
||||
player.yellowMessage("Ronan - Freelance Developer");
|
||||
player.yellowMessage("Vcoc - Freelance Developer");
|
||||
break;
|
||||
|
||||
case "lastrestart":
|
||||
@@ -451,7 +452,7 @@ public class Commands {
|
||||
output += "#b" + data.getRight() + "#k is dropped by:\r\n";
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT * FROM drop_data WHERE itemid = ? LIMIT 50");
|
||||
PreparedStatement ps = con.prepareStatement("SELECT dropperid FROM drop_data WHERE itemid = ? LIMIT 50");
|
||||
ps.setInt(1, data.getLeft());
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while(rs.next()) {
|
||||
@@ -1513,11 +1514,13 @@ public class Commands {
|
||||
|
||||
case "reloadmap":
|
||||
MapleMap oldMap = c.getPlayer().getMap();
|
||||
MapleMap newMap = c.getChannelServer().getMapFactory().getMap(player.getMapId());
|
||||
MapleMap newMap = c.getChannelServer().getMapFactory().resetMap(player.getMapId());
|
||||
int callerid = c.getPlayer().getId();
|
||||
|
||||
for (MapleCharacter ch : oldMap.getCharacters()) {
|
||||
ch.changeMap(newMap);
|
||||
if(ch.getId() != callerid) ch.dropMessage("You have been relocated due to map reloading. Sorry for the inconvenience.");
|
||||
}
|
||||
oldMap = null;
|
||||
newMap.respawn();
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user