Mystic Doors review + Togglable SrvMessage-BossHP + Map-Event patch

Reviewed Mystic Doors.
Fixed several issues showing up on Duey in uncommon scenarios.
Fixed a concurrency issue with XMLDomMapleData.
Scheduled forward the "lock disposal" action within the source. Now, it's expected that, after a set while, no method should require usage of a disposed lock and, during that while, a supposed "disposed lock" is still available to run (although no new processes is expected to require use of these locks).
Fixed concurrency issues with player's current event instance, generating several inconsistencies when swiftly registering/unregistering from events.
Implemented a mutually exclusive approach for server message - Boss HPbar.
Fixed item-making Kage requiring lv71~80 ETC instead of the expected 81~90.
Removed the possibility to buy cosmetic coupons with mesos through the NPCs.
Sleepywood JQ's no longer gives cash items when they finish the quest repeatedly.
Added Duey trucks in several maps lacking it. Added NPC Duey in New Leaf City.
Fixed scripted quests not calculating QUEST_RATE (if applied) when rewarding experience and meso.
This commit is contained in:
ronancpl
2018-08-07 23:37:24 -03:00
parent cc541f39d5
commit 4c25c07e28
173 changed files with 38064 additions and 37254 deletions

View File

@@ -0,0 +1,75 @@
/*
This file is part of the HeavenMS MapleStory Server
Copyleft (L) 2016 - 2018 RonanLana
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation version 3 as published by
the Free Software Foundation. You may not use, modify or distribute
this program under any other version of the GNU Affero General Public
License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.server.audit;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* @author Ronan
*/
public class LockCollector {
private static final LockCollector instance = new LockCollector();
private Map<Runnable, Integer> disposableLocks = new HashMap<>(200);
private final Lock lock = new ReentrantLock(true);
public static LockCollector getInstance() {
return instance;
}
public void registerDisposeAction(Runnable r) {
lock.lock();
try {
disposableLocks.put(r, 0);
} finally {
lock.unlock();
}
}
public void runLockCollector() {
List<Runnable> toDispose = new ArrayList<>();
lock.lock();
try {
for(Entry<Runnable, Integer> e : disposableLocks.entrySet()) {
Integer eVal = e.getValue();
if(eVal > 5) { // updates each 2min
toDispose.add(e.getKey());
} else {
disposableLocks.put(e.getKey(), ++eVal);
}
}
} finally {
lock.unlock();
}
for(Runnable r : toDispose) {
r.run();
}
}
}

View File

@@ -57,7 +57,7 @@ public class ThreadTracker {
private final Map<Long, AtomicInteger> lockCount = new HashMap<>();
private final Map<Long, MonitoredLockType> lockIds = new HashMap<>();
private final Map<Long, Long> lockThreads = new HashMap<>();
private final Map<Long, Byte> lockUpdate = new HashMap<>();
private final Map<Long, Integer> lockUpdate = new HashMap<>();
private final Map<MonitoredLockType, Map<Long, Integer>> locks = new HashMap<>();
ScheduledFuture<?> threadTrackerSchedule;
@@ -169,8 +169,8 @@ public class ThreadTracker {
toRemove.clear();
for(Entry<Long, Byte> it : lockUpdate.entrySet()) {
byte val = (byte)(it.getValue() + 1);
for(Entry<Long, Integer> it : lockUpdate.entrySet()) {
int val = it.getValue() + 1;
if(val < 60) {
lockUpdate.put(it.getKey(), val);
@@ -202,7 +202,7 @@ public class ThreadTracker {
lockCount.put(lockOid, c);
lockIds.put(lockOid, lockId);
lockThreads.put(lockOid, tid);
lockUpdate.put(lockOid, (byte) 0);
lockUpdate.put(lockOid, 0);
}
c.incrementAndGet();
@@ -233,7 +233,7 @@ public class ThreadTracker {
else {
AtomicInteger c = lockCount.get(lockOid);
c.decrementAndGet();
lockUpdate.put(lockOid, (byte) 0);
lockUpdate.put(lockOid, 0);
List<MonitoredLockType> list = threadTracker.get(tid);
for(int i = list.size() - 1; i >= 0; i--) {

View File

@@ -30,6 +30,7 @@ public enum MonitoredLockType {
CHARACTER_EFF,
CHARACTER_PET,
CHARACTER_PRT,
CHARACTER_EVT,
CLIENT,
CLIENT_ENCODER,
CLIENT_LOGIN,
@@ -40,6 +41,7 @@ public enum MonitoredLockType {
SRVHANDLER_TEMP,
BUFF_STORAGE,
PLAYER_STORAGE,
PLAYER_DOOR,
SERVER,
SERVER_DISEASES,
SERVER_LOGIN,
@@ -59,7 +61,7 @@ public enum MonitoredLockType {
GUILD,
PARTY,
WORLD_PARTY,
WORLD_OWL,
WORLD_SRVMESSAGES,
WORLD_PETS,
WORLD_CHARS,
WORLD_CHANNELS,

View File

@@ -159,11 +159,13 @@ public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements
timeoutSchedule.cancel(false);
timeoutSchedule = null;
}
reentrantCount.set(Integer.MAX_VALUE);
} finally {
state.unlock();
}
//unlock();
return new EmptyReadLock();
return new EmptyReadLock(id);
}
}

View File

@@ -46,7 +46,7 @@ public class TrackerReentrantLock extends ReentrantLock implements MonitoredReen
private final int hashcode;
private final Lock state = new ReentrantLock(true);
private final AtomicInteger reentrantCount = new AtomicInteger(0);
public TrackerReentrantLock(MonitoredLockType id) {
super();
this.id = id;
@@ -161,11 +161,13 @@ public class TrackerReentrantLock extends ReentrantLock implements MonitoredReen
timeoutSchedule.cancel(false);
timeoutSchedule = null;
}
reentrantCount.set(Integer.MAX_VALUE);
} finally {
state.unlock();
}
//unlock();
return new EmptyReentrantLock();
return new EmptyReentrantLock(id);
}
}

View File

@@ -157,11 +157,13 @@ public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implement
timeoutSchedule.cancel(false);
timeoutSchedule = null;
}
reentrantCount.set(Integer.MAX_VALUE);
} finally {
state.unlock();
}
//unlock();
return new EmptyWriteLock();
return new EmptyWriteLock(id);
}
}

View File

@@ -19,26 +19,56 @@
*/
package net.server.audit.locks.empty;
import constants.ServerConstants;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.MonitoredReadLock;
import tools.FilePrinter;
/**
*
* @author RonanLana
*/
public class EmptyReadLock implements MonitoredReadLock {
private final MonitoredLockType id;
public EmptyReadLock(MonitoredLockType type) {
this.id = type;
}
private static String printThreadStack(StackTraceElement[] list) {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone(ServerConstants.TIMEZONE));
String df = dateFormat.format(new Date());
String s = "\r\n" + df + "\r\n";
for(int i = 0; i < list.length; i++) {
s += (" " + list[i].toString() + "\r\n");
}
s += "----------------------------";
return s;
}
@Override
public void lock() {}
public void lock() {
FilePrinter.printError(FilePrinter.DISPOSED_LOCKS, "Captured locking tentative on disposed lock " + id + ":" + printThreadStack(Thread.currentThread().getStackTrace()));
}
@Override
public void unlock() {}
@Override
public boolean tryLock() {
FilePrinter.printError(FilePrinter.DISPOSED_LOCKS, "Captured try-locking tentative on disposed lock " + id + ":" + printThreadStack(Thread.currentThread().getStackTrace()));
return false;
}
@Override
public MonitoredReadLock dispose() {
return null;
return this;
}
}

View File

@@ -19,26 +19,56 @@
*/
package net.server.audit.locks.empty;
import constants.ServerConstants;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.MonitoredReentrantLock;
import tools.FilePrinter;
/**
*
* @author RonanLana
*/
public class EmptyReentrantLock implements MonitoredReentrantLock {
private final MonitoredLockType id;
public EmptyReentrantLock(MonitoredLockType type) {
this.id = type;
}
private static String printThreadStack(StackTraceElement[] list) {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone(ServerConstants.TIMEZONE));
String df = dateFormat.format(new Date());
String s = "\r\n" + df + "\r\n";
for(int i = 0; i < list.length; i++) {
s += (" " + list[i].toString() + "\r\n");
}
s += "----------------------------";
return s;
}
@Override
public void lock() {}
public void lock() {
FilePrinter.printError(FilePrinter.DISPOSED_LOCKS, "Captured locking tentative on disposed lock " + id + ":" + printThreadStack(Thread.currentThread().getStackTrace()));
}
@Override
public void unlock() {}
@Override
public boolean tryLock() {
FilePrinter.printError(FilePrinter.DISPOSED_LOCKS, "Captured try-locking tentative on disposed lock " + id + ":" + printThreadStack(Thread.currentThread().getStackTrace()));
return false;
}
@Override
public MonitoredReentrantLock dispose() {
return null;
return this;
}
}

View File

@@ -19,26 +19,56 @@
*/
package net.server.audit.locks.empty;
import constants.ServerConstants;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.MonitoredWriteLock;
import tools.FilePrinter;
/**
*
* @author RonanLana
*/
public class EmptyWriteLock implements MonitoredWriteLock {
private final MonitoredLockType id;
public EmptyWriteLock(MonitoredLockType type) {
this.id = type;
}
private static String printThreadStack(StackTraceElement[] list) {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone(ServerConstants.TIMEZONE));
String df = dateFormat.format(new Date());
String s = "\r\n" + df + "\r\n";
for(int i = 0; i < list.length; i++) {
s += (" " + list[i].toString() + "\r\n");
}
s += "----------------------------";
return s;
}
@Override
public void lock() {}
public void lock() {
FilePrinter.printError(FilePrinter.DISPOSED_LOCKS, "Captured locking tentative on disposed lock " + id + ":" + printThreadStack(Thread.currentThread().getStackTrace()));
}
@Override
public void unlock() {}
@Override
public boolean tryLock() {
FilePrinter.printError(FilePrinter.DISPOSED_LOCKS, "Captured try-locking tentative on disposed lock " + id + ":" + printThreadStack(Thread.currentThread().getStackTrace()));
return false;
}
@Override
public MonitoredWriteLock dispose() {
return null;
return this;
}
}