hpDec fix + Save quest expiration
Fixed an issue that would let a player to delay or anticipate the next map hpDec proc in certain conditions. Implemented mechanic that enables the DB save of expiration times for quests that needs this.
This commit is contained in:
@@ -1974,7 +1974,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
public void run() {
|
||||
doHurtHp();
|
||||
}
|
||||
}, lastHpTask);
|
||||
}, 10000 - lastHpTask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2999,6 +2999,17 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public final MapleQuestStatus getMapleQuestStatus(final int quest) {
|
||||
synchronized (quests) {
|
||||
for (final MapleQuestStatus q : quests.values()) {
|
||||
if (q.getQuest().getId() == quest) {
|
||||
return q;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public MapleQuestStatus getQuest(MapleQuest quest) {
|
||||
synchronized (quests) {
|
||||
@@ -4072,6 +4083,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
if (cTime > -1) {
|
||||
status.setCompletionTime(cTime * 1000);
|
||||
}
|
||||
|
||||
long eTime = rs.getLong("expires");
|
||||
if (eTime > 0) {
|
||||
status.setExpirationTime(eTime);
|
||||
}
|
||||
|
||||
status.setForfeited(rs.getInt("forfeited"));
|
||||
ret.quests.put(q.getId(), status);
|
||||
pse.setInt(1, rs.getInt("queststatusid"));
|
||||
@@ -4179,6 +4196,14 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void reloadQuestExpirations() {
|
||||
for(MapleQuestStatus mqs: quests.values()) {
|
||||
if(mqs.getExpirationTime() > 0) {
|
||||
questTimeLimit2(mqs.getQuest(), mqs.getExpirationTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String makeMapleReadable(String in) {
|
||||
String i = in.replace('I', 'i');
|
||||
@@ -5078,7 +5103,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
ps.executeBatch();
|
||||
deleteWhereCharacterId(con, "DELETE FROM eventstats WHERE characterid = ?");
|
||||
deleteWhereCharacterId(con, "DELETE FROM queststatus WHERE characterid = ?");
|
||||
ps = con.prepareStatement("INSERT INTO queststatus (`queststatusid`, `characterid`, `quest`, `status`, `time`, `forfeited`) VALUES (DEFAULT, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
|
||||
ps = con.prepareStatement("INSERT INTO queststatus (`queststatusid`, `characterid`, `quest`, `status`, `time`, `expires`, `forfeited`) VALUES (DEFAULT, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
|
||||
PreparedStatement psf;
|
||||
try (PreparedStatement pse = con.prepareStatement("INSERT INTO questprogress VALUES (DEFAULT, ?, ?, ?)")) {
|
||||
psf = con.prepareStatement("INSERT INTO medalmaps VALUES (DEFAULT, ?, ?)");
|
||||
@@ -5089,7 +5114,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
ps.setInt(2, q.getQuest().getId());
|
||||
ps.setInt(3, q.getStatus().getId());
|
||||
ps.setInt(4, (int) (q.getCompletionTime() / 1000));
|
||||
ps.setInt(5, q.getForfeited());
|
||||
ps.setLong(5, q.getExpirationTime());
|
||||
ps.setInt(6, q.getForfeited());
|
||||
ps.executeUpdate();
|
||||
try (ResultSet rs = ps.getGeneratedKeys()) {
|
||||
rs.next();
|
||||
@@ -5917,22 +5943,43 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
private void expireQuest(MapleQuest quest) {
|
||||
if(getQuestStatus(quest.getId()) == MapleQuestStatus.Status.COMPLETED.getId()) return;
|
||||
if(System.currentTimeMillis() < getMapleQuestStatus(quest.getId()).getExpirationTime()) return;
|
||||
|
||||
announce(MaplePacketCreator.questExpire(quest.getId()));
|
||||
MapleQuestStatus newStatus = new MapleQuestStatus(quest, MapleQuestStatus.Status.NOT_STARTED);
|
||||
newStatus.setForfeited(getQuest(quest).getForfeited() + 1);
|
||||
updateQuest(newStatus);
|
||||
}
|
||||
|
||||
public void questTimeLimit(final MapleQuest quest, int seconds) {
|
||||
final MapleCharacter chr = this;
|
||||
ScheduledFuture<?> sf = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(chr.getQuestStatus(quest.getId()) == MapleQuestStatus.Status.COMPLETED.getId()) return;
|
||||
|
||||
announce(MaplePacketCreator.questExpire(quest.getId()));
|
||||
MapleQuestStatus newStatus = new MapleQuestStatus(quest, MapleQuestStatus.Status.NOT_STARTED);
|
||||
newStatus.setForfeited(getQuest(quest).getForfeited() + 1);
|
||||
updateQuest(newStatus);
|
||||
expireQuest(quest);
|
||||
}
|
||||
}, seconds * 1000);
|
||||
announce(MaplePacketCreator.addQuestTimeLimit(quest.getId(), seconds * 1000));
|
||||
timers.add(sf);
|
||||
}
|
||||
|
||||
public void questTimeLimit2(final MapleQuest quest, long expires) {
|
||||
long timeLeft = expires - System.currentTimeMillis();
|
||||
|
||||
if(timeLeft <= 0) {
|
||||
expireQuest(quest);
|
||||
} else {
|
||||
ScheduledFuture<?> sf = TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
expireQuest(quest);
|
||||
}
|
||||
}, timeLeft);
|
||||
|
||||
timers.add(sf);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSingleStat(MapleStat stat, int newval) {
|
||||
updateSingleStat(stat, newval, false);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MapleQuestStatus {
|
||||
private Map<Integer, String> progress = new LinkedHashMap<Integer, String>();
|
||||
private List<Integer> medalProgress = new LinkedList<Integer>();
|
||||
private int npc;
|
||||
private long completionTime;
|
||||
private long completionTime, expirationTime;
|
||||
private int forfeited = 0;
|
||||
private String customData;
|
||||
|
||||
@@ -71,6 +71,7 @@ public class MapleQuestStatus {
|
||||
this.questID = quest.getId();
|
||||
this.setStatus(status);
|
||||
this.completionTime = System.currentTimeMillis();
|
||||
this.expirationTime = 0;
|
||||
if (status == Status.STARTED)
|
||||
registerMobs();
|
||||
}
|
||||
@@ -80,6 +81,7 @@ public class MapleQuestStatus {
|
||||
this.setStatus(status);
|
||||
this.setNpc(npc);
|
||||
this.completionTime = System.currentTimeMillis();
|
||||
this.expirationTime = 0;
|
||||
if (status == Status.STARTED) {
|
||||
registerMobs();
|
||||
}
|
||||
@@ -89,9 +91,9 @@ public class MapleQuestStatus {
|
||||
return MapleQuest.getInstance(questID);
|
||||
}
|
||||
|
||||
public short getQuestID() {
|
||||
return questID;
|
||||
}
|
||||
public short getQuestID() {
|
||||
return questID;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
@@ -178,6 +180,14 @@ public class MapleQuestStatus {
|
||||
public void setCompletionTime(long completionTime) {
|
||||
this.completionTime = completionTime;
|
||||
}
|
||||
|
||||
public long getExpirationTime() {
|
||||
return expirationTime;
|
||||
}
|
||||
|
||||
public void setExpirationTime(long expirationTime) {
|
||||
this.expirationTime = expirationTime;
|
||||
}
|
||||
|
||||
public int getForfeited() {
|
||||
return forfeited;
|
||||
|
||||
@@ -242,6 +242,8 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
if(pet != null)
|
||||
player.startFullnessSchedule(PetDataFactory.getHunger(pet.getItemId()), pet, player.getPetIndex(pet));
|
||||
}
|
||||
|
||||
player.reloadQuestExpirations();
|
||||
}
|
||||
|
||||
c.announce(MaplePacketCreator.updateGender(player));
|
||||
@@ -264,7 +266,6 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.earnTitleMessage("GM " + player.getName() + " has logged in"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (player.getMap().getHPDec() > 0) player.resetHpDecreaseTask();
|
||||
|
||||
@@ -69,7 +69,7 @@ public class EventManager {
|
||||
private List<Boolean> openedLobbys;
|
||||
private Properties props = new Properties();
|
||||
private String name;
|
||||
private Lock l = new ReentrantLock();
|
||||
private Lock lobbyLock = new ReentrantLock();
|
||||
|
||||
private static final int limitGuilds = 10; // max numbers of guilds in queue for GPQ.
|
||||
private static final int maxLobbys = 8; // an event manager holds up to this amount of concurrent lobbys
|
||||
@@ -202,32 +202,32 @@ public class EventManager {
|
||||
}
|
||||
|
||||
private boolean getLockLobby(int lobbyId) {
|
||||
l.lock();
|
||||
lobbyLock.lock();
|
||||
try {
|
||||
return openedLobbys.get(lobbyId);
|
||||
} finally {
|
||||
l.unlock();
|
||||
lobbyLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void setLockLobby(int lobbyId, boolean lock) {
|
||||
l.lock();
|
||||
lobbyLock.lock();
|
||||
try {
|
||||
openedLobbys.set(lobbyId, lock);
|
||||
} finally {
|
||||
l.unlock();
|
||||
lobbyLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean startLobbyInstance(int lobbyId) {
|
||||
l.lock();
|
||||
lobbyLock.lock();
|
||||
try {
|
||||
if(!openedLobbys.get(lobbyId)) {
|
||||
openedLobbys.set(lobbyId, true);
|
||||
return true;
|
||||
}
|
||||
} finally {
|
||||
l.unlock();
|
||||
lobbyLock.unlock();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class MapleQuest {
|
||||
|
||||
private static Map<Integer, MapleQuest> quests = new HashMap<>();
|
||||
protected short infoNumber, id;
|
||||
protected int timeLimit;
|
||||
protected int timeLimit, timeLimit2;
|
||||
protected String infoex;
|
||||
protected Map<MapleQuestRequirementType, MapleQuestRequirement> startReqs = new EnumMap<>(MapleQuestRequirementType.class);
|
||||
protected Map<MapleQuestRequirementType, MapleQuestRequirement> completeReqs = new EnumMap<>(MapleQuestRequirementType.class);
|
||||
@@ -74,7 +74,7 @@ public class MapleQuest {
|
||||
MapleData reqInfo = questInfo.getChildByPath(String.valueOf(id));
|
||||
if(reqInfo != null) {
|
||||
timeLimit = MapleDataTool.getInt("timeLimit", reqInfo, 0);
|
||||
timeLimit = Math.max(timeLimit, MapleDataTool.getInt("timeLimit2", reqInfo, 0)); // alas, nexon made we deal with 2 timeLimits
|
||||
timeLimit2 = MapleDataTool.getInt("timeLimit2", reqInfo, 0);
|
||||
autoStart = MapleDataTool.getInt("autoStart", reqInfo, 0) == 1;
|
||||
autoPreComplete = MapleDataTool.getInt("autoPreComplete", reqInfo, 0) == 1;
|
||||
autoComplete = MapleDataTool.getInt("autoComplete", reqInfo, 0) == 1;
|
||||
@@ -287,8 +287,13 @@ public class MapleQuest {
|
||||
newStatus.setForfeited(c.getQuest(this).getForfeited());
|
||||
|
||||
if (timeLimit > 0) {
|
||||
newStatus.setExpirationTime(System.currentTimeMillis() + (timeLimit * 1000));
|
||||
c.questTimeLimit(this, timeLimit);
|
||||
}
|
||||
if (timeLimit2 > 0) {
|
||||
newStatus.setExpirationTime(System.currentTimeMillis() + timeLimit2);
|
||||
c.questTimeLimit2(this, newStatus.getExpirationTime());
|
||||
}
|
||||
|
||||
c.updateQuest(newStatus);
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user