Dynamic World/Channel shutdown + Equip levels on Duey + AP/SP patch

Implemented dynamic world/channel shutdown, coupling with the dynamic deployment from last commit rendering on a fully automated world/channel management.
Fixed some spawned mobs not being properly registered on events.
Implemented a respawn mechanic sensitive to number of players on map. More mobs will spawn the greater the number of players is. Server flag: USE_ENABLE_FULL_RESPAWN = false.
Implemented a mechanic for delayed mob loot drops, on which the delay is determined by the death animation duration. Server flag: USE_SPAWN_LOOT_ON_ANIMATION = true.
Fixed EIM being disposed incorrectly when the dispose is called through scripts.
Protected concurrently AP and SP distribution handlers.
Slightly improved HealOvertimeHandler performance.
Fixed Duey not propagating equipment level and experience when transfering items.
Buyback now has a short grace period, granting the returning player time for decision making (players won't die right away, rather sticks at 1HP).
Reviewed item monitor task not properly protected concurrently.
Fixed some issues with ropes on some Kampung Village maps.
Fixed "maxhpmp" command allowing to pass negative values.
This commit is contained in:
ronancpl
2018-07-28 22:00:52 -03:00
parent 8aadf7c369
commit cc541f39d5
77 changed files with 33492 additions and 32661 deletions

View File

@@ -47,11 +47,13 @@ import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import net.server.audit.locks.MonitoredReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import java.util.Set;
import java.util.HashSet;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import scripting.event.EventInstanceManager;
import server.TimerManager;
@@ -76,7 +78,9 @@ import tools.DatabaseConnection;
import tools.MaplePacketCreator;
import tools.Pair;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.MonitoredReentrantLock;
import net.server.audit.locks.MonitoredReentrantReadWriteLock;
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
/**
*
@@ -99,11 +103,11 @@ public class World {
private PlayerStorage players = new PlayerStorage();
private final ReentrantReadWriteLock chnLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.WORLD_CHANNELS, true);
private final ReentrantReadWriteLock.ReadLock chnRLock = chnLock.readLock();
private final ReentrantReadWriteLock.WriteLock chnWLock = chnLock.writeLock();
private ReadLock chnRLock = chnLock.readLock();
private WriteLock chnWLock = chnLock.writeLock();
private Map<Integer, SortedMap<Integer, MapleCharacter>> accountChars = new HashMap<>();
private MonitoredReentrantLock accountCharsLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_CHARS, true);
private MonitoredReentrantLock accountCharsLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_CHARS, true);
private Set<Integer> queuedGuilds = new HashSet<>();
private Map<Integer, Pair<Pair<Boolean, Boolean>, Pair<Integer, Integer>>> queuedMarriages = new HashMap<>();
@@ -112,31 +116,31 @@ public class World {
private Map<Integer, Integer> partyChars = new HashMap<>();
private Map<Integer, MapleParty> parties = new HashMap<>();
private AtomicInteger runningPartyId = new AtomicInteger();
private MonitoredReentrantLock partyLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_PARTY, true);
private MonitoredReentrantLock partyLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_PARTY, true);
private Map<Integer, Integer> owlSearched = new LinkedHashMap<>();
private MonitoredReentrantLock owlLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_OWL);
private MonitoredReentrantLock owlLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_OWL);
private MonitoredReentrantLock activePetsLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_PETS, true);
private MonitoredReentrantLock activePetsLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_PETS, true);
private Map<Integer, Byte> activePets = new LinkedHashMap<>();
private ScheduledFuture<?> petsSchedule;
private long petUpdate;
private MonitoredReentrantLock activeMountsLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_MOUNTS, true);
private MonitoredReentrantLock activeMountsLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_MOUNTS, true);
private Map<Integer, Byte> activeMounts = new LinkedHashMap<>();
private ScheduledFuture<?> mountsSchedule;
private long mountUpdate;
private MonitoredReentrantLock activePlayerShopsLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_PSHOPS, true);
private MonitoredReentrantLock activePlayerShopsLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_PSHOPS, true);
private Map<Integer, MaplePlayerShop> activePlayerShops = new LinkedHashMap<>();
private MonitoredReentrantLock activeMerchantsLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_MERCHS, true);
private MonitoredReentrantLock activeMerchantsLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_MERCHS, true);
private Map<Integer, Pair<MapleHiredMerchant, Byte>> activeMerchants = new LinkedHashMap<>();
private long merchantUpdate;
private Map<Runnable, Long> registeredTimedMapObjects = new LinkedHashMap<>();
private ScheduledFuture<?> timedMapObjectsSchedule;
private MonitoredReentrantLock timedMapObjectLock = new MonitoredReentrantLock(MonitoredLockType.WORLD_MAPOBJS, true);
private MonitoredReentrantLock timedMapObjectLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_MAPOBJS, true);
private ScheduledFuture<?> charactersSchedule;
private ScheduledFuture<?> marriagesSchedule;
@@ -216,7 +220,7 @@ public class World {
chnRLock.unlock();
}
if(ch == null || ch.getPlayerStorage().getSize() > 0) {
if(ch == null || !ch.canUninstall()) {
return -1;
}
@@ -235,6 +239,18 @@ public class World {
return ch.getId();
}
public boolean canUninstall() {
if(players.getSize() > 0) return false;
for(Channel ch : this.getChannels()) {
if(!ch.canUninstall()) {
return false;
}
}
return true;
}
public void setFlag(byte b) {
this.flag = b;
}
@@ -401,11 +417,17 @@ public class World {
return players;
}
public void addPlayer(MapleCharacter chr) {
players.addPlayer(chr);
}
public void removePlayer(MapleCharacter chr) {
if(!getChannel(chr.getClient().getChannel()).removePlayer(chr)) {
if(!chr.getClient().getChannelServer().removePlayer(chr)) {
Channel cserv = chr.getClient().getChannelServer();
if(cserv != null) {
if(!cserv.removePlayer(chr)) {
// oy the player is not where it should be, find this mf
for(Channel ch : getChannels()) {
if(ch.removePlayer(chr)) {
break;
@@ -1661,14 +1683,14 @@ public class World {
p.disposeLocks();
}
accountCharsLock.dispose();
partyLock.dispose();
owlLock.dispose();
activePetsLock.dispose();
activeMountsLock.dispose();
activePlayerShopsLock.dispose();
activeMerchantsLock.dispose();
timedMapObjectLock.dispose();
accountCharsLock = accountCharsLock.dispose();
partyLock = partyLock.dispose();
owlLock = owlLock.dispose();
activePetsLock = activePetsLock.dispose();
activeMountsLock = activeMountsLock.dispose();
activePlayerShopsLock = activePlayerShopsLock.dispose();
activeMerchantsLock = activeMerchantsLock.dispose();
timedMapObjectLock = timedMapObjectLock.dispose();
}
public final void shutdown() {
@@ -1702,6 +1724,8 @@ public class World {
}
players.disconnectAll();
players = null;
disposeLocks();
}
}