Buff System & Map skipping fix + properly disposing Storage + Fairness to locks

Fixed buff system behaving oddly if a buff has value zero, that would render some skills "broken".
Fixed players skipping maps when trying to access portals while under a poor Internet connection.
Fixed storage not disposing players properly in cases where the players does not meet the storage conditions.
Set some locks to use fairness strategy when dealing with atomic code, in order to make the calls to it properly synchronized.
Fixed Aran introductory questline stucking players when certain conditions were met.
Added drop data for some mob versions of Fairy, Yeti and Pepe.
This commit is contained in:
ronancpl
2017-10-29 16:02:50 -02:00
parent 5f1abf3fb3
commit 44949aea37
119 changed files with 760 additions and 32399 deletions
+24 -10
View File
@@ -31,6 +31,8 @@ import java.util.List;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import net.SendOpcode;
import server.maps.AbstractMapleMapObject;
import server.maps.MapleMapObjectType;
@@ -53,6 +55,7 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
private List<String> bannedList = new ArrayList<>();
private List<Pair<MapleCharacter, String>> chatLog = new LinkedList<>();
private Map<Integer, Byte> chatSlot = new LinkedHashMap<>();
private Lock visitorLock = new ReentrantLock(true);
public MaplePlayerShop(MapleCharacter owner, String description) {
this.setPosition(owner.getPosition());
@@ -322,8 +325,11 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
}
public void sendShop(MapleClient c) {
synchronized(visitors) {
visitorLock.lock();
try {
c.announce(MaplePacketCreator.getPlayerShop(this, isOwner(c.getPlayer())));
} finally {
visitorLock.unlock();
}
}
@@ -332,11 +338,14 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
}
public MapleCharacter[] getVisitors() {
synchronized(visitors) {
visitorLock.lock();
try {
MapleCharacter[] copy = new MapleCharacter[3];
for(int i = 0; i < visitors.length; i++) copy[i] = visitors[i];
return copy;
} finally {
visitorLock.unlock();
}
}
@@ -370,13 +379,16 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
}
MapleCharacter target = null;
synchronized(visitors) {
visitorLock.lock();
try {
for (int i = 0; i < 3; i++) {
if (visitors[i] != null && visitors[i].getName().equals(name)) {
target = visitors[i];
break;
}
}
} finally {
visitorLock.unlock();
}
if(target != null) {
@@ -400,15 +412,17 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
return false;
}
if (this.hasFreeSlot() && !this.isVisitor(chr)) {
this.addVisitor(chr);
chr.setPlayerShop(this);
this.sendShop(chr.getClient());
synchronized (visitors) {
if (this.hasFreeSlot() && !this.isVisitor(chr)) {
this.addVisitor(chr);
chr.setPlayerShop(this);
this.sendShop(chr.getClient());
return true;
return true;
}
return false;
}
return false;
}
public List<MaplePlayerShopItem> sendAvailableBundles(int itemid) {
+12 -9
View File
@@ -191,6 +191,7 @@ public class MapleStatEffect {
ret.duration *= 1000; // items have their times stored in ms, of course
ret.overTime = overTime;
}
ArrayList<Pair<MapleBuffStat, Integer>> statups = new ArrayList<>();
ret.watk = (short) MapleDataTool.getInt("pad", source, 0);
ret.wdef = (short) MapleDataTool.getInt("pdd", source, 0);
@@ -206,15 +207,6 @@ public class MapleStatEffect {
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MAP_PROTECTION, Integer.valueOf(ret.mapProtection));
if (ret.overTime && ret.getSummonMovementType() == null) {
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WATK, Integer.valueOf(ret.watk));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WDEF, Integer.valueOf(ret.wdef));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MATK, Integer.valueOf(ret.matk));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MDEF, Integer.valueOf(ret.mdef));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.ACC, Integer.valueOf(ret.acc));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.AVOID, Integer.valueOf(ret.avoid));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.SPEED, Integer.valueOf(ret.speed));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.JUMP, Integer.valueOf(ret.jump));
if(!skill) {
if(isPyramidBuff(sourceid)) {
ret.berserk = MapleDataTool.getInt("berserk", source, 0);
@@ -273,7 +265,17 @@ public class MapleStatEffect {
ret.speed *= 15;
}
}
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WATK, Integer.valueOf(ret.watk));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WDEF, Integer.valueOf(ret.wdef));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MATK, Integer.valueOf(ret.matk));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MDEF, Integer.valueOf(ret.mdef));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.ACC, Integer.valueOf(ret.acc));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.AVOID, Integer.valueOf(ret.avoid));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.SPEED, Integer.valueOf(ret.speed));
addBuffStatPairToListIfNotZero(statups, MapleBuffStat.JUMP, Integer.valueOf(ret.jump));
}
MapleData ltd = source.getChildByPath("lt");
if (ltd != null) {
ret.lt = (Point) ltd.getData();
@@ -730,6 +732,7 @@ public class MapleStatEffect {
applyto.toggleHide(false);
return true;
}
int hpchange = calcHPChange(applyfrom, primary);
int mpchange = calcMPChange(applyfrom, primary);
+9 -2
View File
@@ -27,7 +27,6 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -51,7 +50,7 @@ public class MapleStorage {
private byte slots;
private Map<MapleInventoryType, List<Item>> typeItems = new HashMap<>();
private List<Item> items;
private Lock lock = new ReentrantLock();
private Lock lock = new ReentrantLock(true);
private MapleStorage(int id, byte slots, int meso) {
this.id = id;
@@ -224,6 +223,14 @@ public class MapleStorage {
}
public void sendStorage(MapleClient c, int npcId) {
/*
if (c.getPlayer().getLevel() < 15){
c.getPlayer().message("You may only use the storage once you have reached level 15.");
c.announce(MaplePacketCreator.enableActions());
return;
}
*/
final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
lock.lock();
+11 -7
View File
@@ -14,7 +14,7 @@ import server.TimerManager;
public class BalrogPQ {
public static final int[] EasyBalrogParts = {8830002, 8830003, 8830000};
public static final int[] HardBalrogParts = {8830000, 8830001, 8830002};
public static List<MapleCharacter> candidates = new ArrayList<MapleCharacter>();
public static List<MapleCharacter> candidates = new ArrayList<>();
public static boolean hasStarted = false;
public static String partyLeader = "undefined";
public static boolean balrogSpawned = false;
@@ -28,8 +28,10 @@ public class BalrogPQ {
}
public static void warpAllCandidates(){
for(MapleCharacter c : candidates){
c.changeMap(105100300);
synchronized(candidates){
for(MapleCharacter c : candidates){
c.changeMap(105100300);
}
}
}
@@ -48,7 +50,7 @@ public class BalrogPQ {
TimerManager tMan = TimerManager.getInstance();
tMan.schedule(new Runnable(){
@Override
public void run(){
public void run(){
for(MapleCharacter chrs : fmap.getCharacters()){
chrs.changeMap(105100100);
chrs.message("You did not defeat the balrog in time..");
@@ -57,9 +59,9 @@ public class BalrogPQ {
}
} , 60 * 60 * 1000);
tMan.schedule(new Runnable(){
tMan.schedule(new Runnable(){
@Override
public void run(){
public void run(){
if(fmap.getCharacters().size() <= 3){
if(fmap.getCharacters().size() > 0){
for(MapleCharacter chrs : fmap.getCharacters()){
@@ -92,7 +94,9 @@ public class BalrogPQ {
hasStarted = false;
balrogSpawned = false;
partyLeader = "undefined";
candidates.clear();
synchronized(candidates){
candidates.clear();
}
timeStamp = 0;
}
public static void spawnBalrog(int mode, MapleCharacter chr){
+1 -1
View File
@@ -85,7 +85,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
private final HashMap<Integer, AtomicInteger> takenDamage = new HashMap<>();
private ReentrantLock externalLock = new ReentrantLock();
private ReentrantLock monsterLock = new ReentrantLock();
private ReentrantLock monsterLock = new ReentrantLock(true);
private ReentrantLock statiLock = new ReentrantLock();
public MapleMonster(int id, MapleMonsterStats stats) {
+29 -15
View File
@@ -36,6 +36,8 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import net.server.Server;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
@@ -50,7 +52,6 @@ import tools.Pair;
* @author Ronan (concurrency protection)
*/
public class MapleHiredMerchant extends AbstractMapleMapObject {
private int ownerId, itemId, mesos = 0;
private int channel, world;
private long start;
@@ -62,6 +63,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
private List<SoldItem> sold = new LinkedList<>();
private AtomicBoolean open = new AtomicBoolean();
private MapleMap map;
private Lock visitorLock = new ReentrantLock(true);
public MapleHiredMerchant(final MapleCharacter owner, int itemId, String desc) {
this.setPosition(owner.getPosition());
@@ -76,8 +78,11 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
public void broadcastToVisitorsThreadsafe(final byte[] packet) {
synchronized(visitors) {
visitorLock.lock();
try {
broadcastToVisitors(packet);
} finally {
visitorLock.unlock();
}
}
@@ -90,7 +95,8 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
public boolean addVisitor(MapleCharacter visitor) {
synchronized(visitors) {
visitorLock.lock();
try {
int i = this.getFreeSlot();
if (i > -1) {
visitors[i] = visitor;
@@ -100,25 +106,33 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
return false;
} finally {
visitorLock.unlock();
}
}
public void removeVisitor(MapleCharacter visitor) {
synchronized(visitors) {
visitorLock.lock();
try {
int slot = getVisitorSlot(visitor);
if (slot < 0){ //Not found
return;
if (slot < 0) { //Not found
return;
}
if (visitors[slot] != null && visitors[slot].getId() == visitor.getId()) {
visitors[slot] = null;
broadcastToVisitors(MaplePacketCreator.hiredMerchantVisitorLeave(slot + 1));
}
} finally {
visitorLock.unlock();
}
}
public int getVisitorSlotThreadsafe(MapleCharacter visitor) {
synchronized(visitors) {
visitorLock.lock();
try {
return getVisitorSlot(visitor);
} finally {
visitorLock.unlock();
}
}
@@ -132,7 +146,8 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
public void removeAllVisitors() {
synchronized(visitors) {
visitorLock.lock();
try {
for (int i = 0; i < 3; i++) {
if (visitors[i] != null) {
visitors[i].setHiredMerchant(null);
@@ -143,6 +158,8 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
visitors[i] = null;
}
}
} finally {
visitorLock.unlock();
}
}
@@ -314,11 +331,14 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
public MapleCharacter[] getVisitors() {
synchronized(visitors) {
visitorLock.lock();
try {
MapleCharacter[] copy = new MapleCharacter[3];
for(int i = 0; i < visitors.length; i++) copy[i] = visitors[i];
return copy;
} finally {
visitorLock.unlock();
}
}
@@ -362,12 +382,6 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
}
}
public int getFreeSlotThreadsafe() {
synchronized(visitors) {
return getFreeSlot();
}
}
private int getFreeSlot() {
for (int i = 0; i < 3; i++) {
if (visitors[i] == null) {
+1 -1
View File
@@ -2724,7 +2724,6 @@ public class MapleMap {
if (reactor.getShouldCollect() == true && mapitem != null && mapitem == getMapObject(mapitem.getObjectId())) {
mapitem.lockItem();
try {
TimerManager tMan = TimerManager.getInstance();
if (mapitem.isPickedUp()) {
return;
}
@@ -2735,6 +2734,7 @@ public class MapleMap {
reactor.hitReactor(c);
if (reactor.getDelay() > 0) {
TimerManager tMan = TimerManager.getInstance();
tMan.schedule(new Runnable() {
@Override
public void run() {
+1 -1
View File
@@ -22,7 +22,7 @@ import tools.MaplePacketCreator;
public class MapleMiniDungeon {
List<MapleCharacter> players = new ArrayList<>();
ScheduledFuture<?> timeoutTask = null;
Lock lock = new ReentrantLock();
Lock lock = new ReentrantLock(true);
int baseMap;
long expireTime;
+1 -1
View File
@@ -59,7 +59,7 @@ public class MapleReactor extends AbstractMapleMapObject {
this.evstate = (byte)0;
this.stats = stats;
this.rid = rid;
alive = true;
this.alive = true;
}
public void setShouldCollect(boolean collect) {