Concurrency fix + new scripts

Fixed some situation involving concurrency upon using getCharacters()
from MapleMap, added scripts and other bug fixes.
This commit is contained in:
ronancpl
2017-04-08 19:29:27 -03:00
parent c8f905e1a5
commit 7dc163fc76
38 changed files with 684 additions and 180 deletions

View File

@@ -64,13 +64,12 @@ public final class SkillBookHandler extends AbstractMaplePacketHandler {
canuse = false;
} else if ((player.getSkillLevel(skill2) >= skilldata.get("reqSkillLevel") || skilldata.get("reqSkillLevel") == 0) && player.getMasterLevel(skill2) < skilldata.get("masterLevel")) {
canuse = true;
if (Randomizer.nextInt(101) < skilldata.get("success") && skilldata.get("success") != 0) {
if (MapleItemInformationProvider.rollSuccessChance(skilldata.get("success"))) {
success = true;
player.changeSkillLevel(skill2, player.getSkillLevel(skill2), Math.max(skilldata.get("masterLevel"), player.getMasterLevel(skill2)), -1);
} else {
success = false;
player.dropMessage("The skill book lights up, but the skill winds up as if nothing happened.");
//player.dropMessage("The skill book lights up, but the skill winds up as if nothing happened.");
}
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);
} else {

View File

@@ -83,6 +83,10 @@ public class AbstractPlayerInteraction {
public MapleCharacter getPlayer() {
return c.getPlayer();
}
public MapleCharacter getChar() {
return c.getPlayer();
}
public void warp(int map) {
getPlayer().changeMap(getWarpMap(map), getWarpMap(map).getPortal(0));

View File

@@ -511,7 +511,7 @@ public class MapleItemInformationProvider {
return scrollId > 2048999 && scrollId < 2049004;
}
private double testYourLuck() {
private static double testYourLuck() {
double result = 100.0, rolled;
int i, j = ServerConstants.SCROLL_CHANCE_RATE;
@@ -524,6 +524,9 @@ public class MapleItemInformationProvider {
return(result);
}
public static boolean rollSuccessChance(double prop) {
return(testYourLuck() <= prop && prop > 0.0);
}
public Item scrollEquipWithId(Item equip, int scrollId, boolean usingWhiteScroll, boolean isGM) {
if (equip instanceof Equip) {
@@ -534,7 +537,7 @@ public class MapleItemInformationProvider {
System.out.println("GM: " + isGM + "\tWS: " + usingWhiteScroll + "\tITEM: " + scrollId);
if (((nEquip.getUpgradeSlots() > 0 || isCleanSlate(scrollId))) || isGM) {
if(isGM || testYourLuck() <= stats.get("success")) {
if(isGM || rollSuccessChance((double)stats.get("success"))) {
short flag = nEquip.getFlag();
switch (scrollId) {
case 2040727:

View File

@@ -250,19 +250,14 @@ public class MapleMonster extends AbstractLoadedMapleLife {
private void distributeExperienceToParty(int pid, int exp, int killer, Map<Integer, Integer> expDist) {
LinkedList<MapleCharacter> members = new LinkedList<>();
map.getCharacterReadLock().lock();
Collection<MapleCharacter> chrs = map.getCharacters();
try {
for (MapleCharacter mc : chrs) {
if (mc.getPartyId() == pid) {
members.add(mc);
}
for (MapleCharacter mc : chrs) {
if (mc.getPartyId() == pid) {
members.add(mc);
}
} finally {
map.getCharacterReadLock().unlock();
}
final int minLevel = getLevel() - 5;
int partyLevel = 0;
@@ -312,29 +307,26 @@ public class MapleMonster extends AbstractLoadedMapleLife {
for (Entry<Integer, AtomicInteger> damage : takenDamage.entrySet()) {
expDist.put(damage.getKey(), (int) (0.80f * exp * damage.getValue().get() / totalHealth));
}
map.getCharacterReadLock().lock(); // avoid concurrent mod
Collection<MapleCharacter> chrs = map.getCharacters();
try {
for (MapleCharacter mc : chrs) {
if (expDist.containsKey(mc.getId())) {
boolean isKiller = mc.getId() == killerId;
int xp = expDist.get(mc.getId());
if (isKiller) {
xp += exp / 5;
}
MapleParty p = mc.getParty();
if (p != null) {
int pID = p.getId();
int pXP = xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0);
partyExp.put(pID, pXP);
} else {
giveExpToCharacter(mc, xp, isKiller, 1);
}
for (MapleCharacter mc : chrs) {
if (expDist.containsKey(mc.getId())) {
boolean isKiller = mc.getId() == killerId;
int xp = expDist.get(mc.getId());
if (isKiller) {
xp += exp / 5;
}
MapleParty p = mc.getParty();
if (p != null) {
int pID = p.getId();
int pXP = xp + (partyExp.containsKey(pID) ? partyExp.get(pID) : 0);
partyExp.put(pID, pXP);
} else {
giveExpToCharacter(mc, xp, isKiller, 1);
}
}
} finally {
map.getCharacterReadLock().unlock();
}
for (Entry<Integer, Integer> party : partyExp.entrySet()) {
distributeExperienceToParty(party.getKey(), party.getValue(), killerId, expDist);
}

View File

@@ -153,14 +153,6 @@ public class MapleMap {
objectWLock = objectLock.writeLock();
}
public ReadLock getCharacterReadLock() {
return chrRLock;
}
public WriteLock getCharacterWriteLock() {
return chrWLock;
}
public void broadcastMessage(MapleCharacter source, final byte[] packet) {
chrRLock.lock();
try {
@@ -1293,9 +1285,11 @@ public class MapleMap {
public void addPlayer(final MapleCharacter chr) {
chrWLock.lock();
chrRLock.lock();
try {
characters.add(chr);
} finally {
chrRLock.unlock();
chrWLock.unlock();
}
chr.setMapId(mapid);
@@ -1534,9 +1528,11 @@ public class MapleMap {
public void removePlayer(MapleCharacter chr) {
chrWLock.lock();
chrRLock.lock();
try {
characters.remove(chr);
} finally {
chrRLock.unlock();
chrWLock.unlock();
}
removeMapObject(chr.getObjectId());
@@ -1794,7 +1790,13 @@ public class MapleMap {
}
public Collection<MapleCharacter> getCharacters() {
return Collections.unmodifiableCollection(this.characters);
chrRLock.lock();
try {
return Collections.unmodifiableCollection(this.characters);
}
finally {
chrRLock.unlock();
}
}
public MapleCharacter getCharacterById(int id) {
@@ -2068,9 +2070,16 @@ public class MapleMap {
}
public void respawn() {
if (characters.isEmpty()) {
return;
chrRLock.lock();
try {
if (characters.isEmpty()) {
return;
}
}
finally {
chrRLock.unlock();
}
short numShouldSpawn = (short) ((monsterSpawn.size() - spawnedMonstersOnMap.get()));//Fking lol'd
if (numShouldSpawn > 0) {
List<SpawnPoint> randomSpawn = new ArrayList<>(monsterSpawn);
@@ -2227,6 +2236,7 @@ public class MapleMap {
if (timeLimit != 0 && timeLimit < System.currentTimeMillis()) {
warpEveryone(getForcedReturnId());
}
if (getCharacters().isEmpty()) {
resetReactors();
killAllMonsters();
@@ -2263,14 +2273,8 @@ public class MapleMap {
}
public void warpEveryone(int to) {
List<MapleCharacter> players;
chrRLock.lock();
try {
players = new ArrayList<>(getCharacters());
} finally {
chrRLock.unlock();
}
List<MapleCharacter> players = new ArrayList<>(getCharacters());
for (MapleCharacter chr : players) {
chr.changeMap(to);
}
@@ -2315,7 +2319,6 @@ public class MapleMap {
public void warpOutByTeam(int team, int mapid) {
List<MapleCharacter> chars = new ArrayList<>(getCharacters());
for (MapleCharacter chr : chars) {
if (chr != null) {
if (chr.getTeam() == team) {