Event Recall + Cash Shop bestsellers + MapleSessionCoordinator rework

Implemented an event recall system. Players that went disconnected during an event instance are able to rejoin the ongoing event upon relogin.
Implemented a player-activity backed best-sellers system for the Cash Shop.
Patched the recently added selective loot system interfering with quest items, ever disabling drops after the player picked up one item.
Implemented a server flag for everlasting buffs.
Fixed some inconsistencies with Priest Dispel skill, sometimes crashing party players.
Fixed change job not properly showing effects for other players.
Fixed wrong fee value being taken from players that expands their guild size. Also, implemented GMS-like fee for this action.
Reworked the MapleSessionCoordinator, now evaluating client's HWID as well as remote IP. This's expected to lessen account drought time for players that are constantly changing their IP.

Last but not least, added world maps for Mushroom Castle, Zipangu, CBD/Malaysia and Ellin Forest regions. Original artwork content used on files depicted in this topic are rightful property of Nexon Corps., these files thoroughly trying to adhere the "Fair Use" disclaimer policy, their purpose being solely to fulfill gaming experience for the areas that were already present on v83 GMS but still lacked worldmaps. For more info regarding Fair Use, please refer to "http://www.dmlp.org/legal-guide/fair-use".
This commit is contained in:
ronancpl
2018-09-07 14:55:29 -03:00
parent 132f286391
commit c3e3c6dfbb
83 changed files with 2718 additions and 626 deletions

View File

@@ -53,14 +53,14 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.enableActions());
return;
}
final int action = slea.readByte();
final int action = slea.readByte();
if (action == 0x03 || action == 0x1E) {
slea.readByte();
final int useNX = slea.readInt();
final int snCS = slea.readInt();
CashItem cItem = CashItemFactory.getItem(snCS);
if (cItem == null || !cItem.isOnSale() || cs.getCash(useNX) < cItem.getPrice()) {
if (!canBuy(cItem, cs.getCash(useNX))) {
FilePrinter.printError(FilePrinter.ITEM, "Denied to sell cash item with SN " + cItem.getSN());
c.announce(MaplePacketCreator.enableActions());
return;
@@ -87,7 +87,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
}
c.announce(MaplePacketCreator.showBoughtCashPackage(cashPackage, c.getAccID()));
}
cs.gainCash(useNX, -cItem.getPrice());
cs.gainCash(useNX, cItem, chr.getWorld());
c.announce(MaplePacketCreator.showCash(chr));
} else if (action == 0x04) {//TODO check for gender
int birthday = slea.readInt();
@@ -113,7 +113,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
}
cs.gift(Integer.parseInt(recipient.get("id")), chr.getName(), message, cItem.getSN());
c.announce(MaplePacketCreator.showGiftSucceed(recipient.get("name"), cItem));
cs.gainCash(4, -cItem.getPrice());
cs.gainCash(4, cItem, chr.getWorld());
c.announce(MaplePacketCreator.showCash(chr));
try {
chr.sendNote(recipient.get("name"), chr.getName() + " has sent you a gift! Go check out the Cash Shop.", (byte) 0); //fame or not
@@ -156,7 +156,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
}
if (chr.gainSlots(type, 8, false)) {
c.announce(MaplePacketCreator.showBoughtInventorySlots(type, chr.getSlots(type)));
cs.gainCash(cash, -cItem.getPrice());
cs.gainCash(cash, cItem, chr.getWorld());
c.announce(MaplePacketCreator.showCash(chr));
}
}
@@ -186,7 +186,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
}
if (chr.getStorage().gainSlots(8)) {
c.announce(MaplePacketCreator.showBoughtStorageSlots(chr.getStorage().getSlots()));
cs.gainCash(cash, -cItem.getPrice());
cs.gainCash(cash, cItem, chr.getWorld());
c.announce(MaplePacketCreator.showCash(chr));
}
}
@@ -202,7 +202,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
if (c.gainCharacterSlot()) {
c.announce(MaplePacketCreator.showBoughtCharacterSlot(c.getCharacterSlots()));
cs.gainCash(cash, -cItem.getPrice());
cs.gainCash(cash, cItem, chr.getWorld());
c.announce(MaplePacketCreator.showCash(chr));
} else {
chr.dropMessage(1, "You have already used up all 12 extra character slots.");
@@ -276,7 +276,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
cs.addToInventory(eqp);
c.announce(MaplePacketCreator.showBoughtCashItem(eqp, c.getAccID()));
cs.gift(partner.getId(), chr.getName(), text, eqp.getSN(), (ringid + 1));
cs.gainCash(toCharge, -itemRing.getPrice());
cs.gainCash(toCharge, itemRing, chr.getWorld());
chr.addCrushRing(MapleRing.loadFromDb(ringid));
try {
chr.sendNote(partner.getName(), text, (byte) 1);
@@ -357,7 +357,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
return c.checkBirthDate(cal);
}
public static boolean canBuy(CashItem item, int cash) {
private static boolean canBuy(CashItem item, int cash) {
return item != null && item.isOnSale() && item.getPrice() <= cash;
}
}

View File

@@ -42,24 +42,23 @@ public final class GiveFameHandler extends AbstractMaplePacketHandler {
if (target == null || target.getId() == player.getId() || player.getLevel() < 15) {
return;
} else if (famechange != 1 && famechange != -1) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit fame.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to fame hack with famechange " + famechange + "\r\n");
c.disconnect(true, false);
return;
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit fame.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to fame hack with famechange " + famechange + "\r\n");
c.disconnect(true, false);
return;
}
FameStatus status = player.canGiveFame(target);
if (status == FameStatus.OK || player.isGM()){
if (Math.abs(target.getFame() + famechange) < 30001) {
target.addFame(famechange);
target.updateSingleStat(MapleStat.FAME, target.getFame());
}
if (!player.isGM()) {
player.hasGivenFame(target);
}
c.announce(MaplePacketCreator.giveFameResponse(mode, target.getName(), target.getFame()));
target.getClient().announce(MaplePacketCreator.receiveFame(mode, player.getName()));
if (status == FameStatus.OK) {
if (target.gainFame(famechange, player, mode)) {
if (!player.isGM()) {
player.hasGivenFame(target);
}
} else {
player.message("Could not process the request, since this character currently has the minimum/maximum level of fame.");
}
} else {
c.announce(MaplePacketCreator.giveFameErrorResponse(status == FameStatus.NOT_TODAY ? 3 : 4));
c.announce(MaplePacketCreator.giveFameErrorResponse(status == FameStatus.NOT_TODAY ? 3 : 4));
}
}
}

View File

@@ -77,7 +77,6 @@ public final class NoteActionHandler extends AbstractMaplePacketHandler {
}
if (fame > 0) {
c.getPlayer().gainFame(fame);
c.announce(MaplePacketCreator.getShowFameGain(fame));
}
}
}

View File

@@ -62,7 +62,11 @@ import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import net.server.coordinator.MapleEventRecallCoordinator;
import net.server.coordinator.MapleSessionCoordinator;
import org.apache.mina.core.session.IoSession;
import server.life.MobSkill;
import scripting.event.EventInstanceManager;
import tools.packets.Wedding;
public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
@@ -79,11 +83,23 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
MapleCharacter player = c.getWorldServer().getPlayerStorage().getCharacterById(cid);
boolean newcomer = false;
if (player == null) {
if(!server.validateCharacteridInTransition((InetSocketAddress) c.getSession().getRemoteAddress(), cid)) {
IoSession session = c.getSession();
if (!server.validateCharacteridInTransition((InetSocketAddress) session.getRemoteAddress(), cid)) {
c.disconnect(true, false);
return;
}
if (ServerConstants.DETERRED_MULTICLIENT) {
String remoteHwid = MapleSessionCoordinator.getInstance().getGameSessionHwid(session);
if (remoteHwid == null) {
c.disconnect(true, false);
return;
}
session.setAttribute(MapleClient.CLIENT_HWID, remoteHwid);
}
try {
player = MapleCharacter.loadCharFromDB(cid, c, true);
newcomer = true;
@@ -263,7 +279,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.requestBuddylistAdd(pendingBuddyRequest.getId(), c.getPlayer().getId(), pendingBuddyRequest.getName()));
}
if(newcomer) {
if (newcomer) {
for(MaplePet pet : player.getPets()) {
if(pet != null)
world.registerPetHunger(player, player.getPetIndex(pet));
@@ -332,6 +348,13 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
partner.announce(Wedding.OnNotifyWeddingPartnerTransfer(player.getId(), player.getMapId()));
}
}
if (newcomer) {
EventInstanceManager eim = MapleEventRecallCoordinator.getInstance().recallEventInstance(cid);
if (eim != null) {
eim.registerPlayer(player);
}
}
}
private static void showDueyNotification(MapleClient c, MapleCharacter player) {

View File

@@ -117,8 +117,8 @@ public final class SpecialMoveHandler extends AbstractMaplePacketHandler {
int gain = lose * (ef.getY() / 100);
chr.setMp(chr.getMp() + gain);
chr.updateSingleStat(MapleStat.MP, chr.getMp());
} else if (skillid == Priest.DISPEL || skillid == SuperGM.HEAL_PLUS_DISPEL) {
slea.skip((skillid == Priest.DISPEL) ? 10 : 11);
} else if (skillid == SuperGM.HEAL_PLUS_DISPEL) {
slea.skip(11);
chr.getMap().broadcastMessage(chr, MaplePacketCreator.showBuffeffect(chr.getId(), skillid, chr.getSkillLevel(skillid)), false);
} else if (skillid % 10000000 == 1004) {
slea.readShort();

View File

@@ -352,7 +352,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
} else if (itemType == 523) {
int itemid = slea.readInt();
if(!ServerConstants.USE_ENFORCE_OWL_SUGGESTIONS) c.getWorldServer().addOwlItemSearch(itemid);
if(!ServerConstants.USE_ENFORCE_ITEM_SUGGESTION) c.getWorldServer().addOwlItemSearch(itemid);
player.setOwlSearch(itemid);
List<Pair<MaplePlayerShopItem, AbstractMapleMapObject>> hmsAvailable = c.getWorldServer().getAvailableItemBundles(itemid);
if(!hmsAvailable.isEmpty()) remove(c, itemId);

View File

@@ -56,7 +56,7 @@ public final class UseOwlOfMinervaHandler extends AbstractMaplePacketHandler {
}
};
PriorityQueue<Pair<Integer, Integer>> queue = new PriorityQueue<>(10, comparator);
PriorityQueue<Pair<Integer, Integer>> queue = new PriorityQueue<>(Math.max(1, owlSearched.size()), comparator);
for(Pair<Integer, Integer> p : owlSearched) {
queue.add(p);
}